-
Notifications
You must be signed in to change notification settings - Fork 3k
/
Copy pathPagingPasscodeViewController.swift
89 lines (77 loc) · 3.07 KB
/
PagingPasscodeViewController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
private let PaneSwipeDuration: TimeInterval = 0.3
/// Base class for implementing a Passcode configuration screen with multiple 'panes'.
class PagingPasscodeViewController: BasePasscodeViewController {
fileprivate lazy var pager: UIScrollView = {
let scrollView = UIScrollView()
scrollView.isPagingEnabled = true
scrollView.isUserInteractionEnabled = false
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
return scrollView
}()
var panes = [PasscodePane]()
var currentPaneIndex: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(pager)
panes.forEach { pager.addSubview($0) }
pager.snp.makeConstraints { make in
make.bottom.left.right.equalTo(self.view)
make.top.equalTo(self.topLayoutGuide.snp.bottom)
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
panes.enumerated().forEach { index, pane in
pane.frame = CGRect(origin: CGPoint(x: CGFloat(index) * pager.frame.width, y: 0), size: pager.frame.size)
}
pager.contentSize = CGSize(width: CGFloat(panes.count) * pager.frame.width, height: pager.frame.height)
scrollToPaneAtIndex(currentPaneIndex)
if self.authenticationInfo?.isLocked() ?? false {
return
}
panes[currentPaneIndex].codeInputView.becomeFirstResponder()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.view.endEditing(true)
}
}
extension PagingPasscodeViewController {
@discardableResult func scrollToNextAndSelect() -> PasscodePane {
scrollToNextPane()
panes[currentPaneIndex].codeInputView.becomeFirstResponder()
return panes[currentPaneIndex]
}
@discardableResult func scrollToPreviousAndSelect() -> PasscodePane {
scrollToPreviousPane()
panes[currentPaneIndex].codeInputView.becomeFirstResponder()
return panes[currentPaneIndex]
}
func resetAllInputFields() {
panes.forEach { $0.codeInputView.resetCode() }
}
func scrollToNextPane() {
guard (currentPaneIndex + 1) < panes.count else {
return
}
currentPaneIndex += 1
scrollToPaneAtIndex(currentPaneIndex)
}
func scrollToPreviousPane() {
guard (currentPaneIndex - 1) >= 0 else {
return
}
currentPaneIndex -= 1
scrollToPaneAtIndex(currentPaneIndex)
}
func scrollToPaneAtIndex(_ index: Int) {
UIView.animate(withDuration: PaneSwipeDuration, delay: 0, options: UIViewAnimationOptions(), animations: {
self.pager.contentOffset = CGPoint(x: CGFloat(self.currentPaneIndex) * self.pager.frame.width, y: 0)
}, completion: nil)
}
}