blockchainethereumblockchain-walleterc20erc721walletxdaidappdecentralizederc1155erc875iosswifttokens
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.7 KiB
135 lines
4.7 KiB
// Copyright SIX DAY LLC. All rights reserved.
|
|
// Copyright © 2018 Stormbird PTE. LTD.
|
|
|
|
import UIKit
|
|
|
|
class LockPasscodeViewController: UIViewController {
|
|
var willFinishWithResult: ((_ success: Bool) -> Void)?
|
|
let model: LockViewModel
|
|
var lockView: LockView!
|
|
let lock = Lock()
|
|
private var invisiblePasscodeField = UITextField()
|
|
private var shouldIgnoreTextFieldDelegateCalls = false
|
|
init(model: LockViewModel) {
|
|
self.model = model
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
override func viewDidLoad() {
|
|
self.navigationItem.hidesBackButton = true
|
|
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
|
|
self.view.backgroundColor = Colors.appBackground
|
|
self.configureInvisiblePasscodeField()
|
|
self.configureNavigationItems()
|
|
self.configureLockView()
|
|
}
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
if !invisiblePasscodeField.isFirstResponder && !lock.incorrectMaxAttemptTimeIsSet() {
|
|
invisiblePasscodeField.becomeFirstResponder()
|
|
}
|
|
}
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
super.viewWillDisappear(animated)
|
|
if invisiblePasscodeField.isFirstResponder {
|
|
invisiblePasscodeField.resignFirstResponder()
|
|
}
|
|
}
|
|
private func configureInvisiblePasscodeField() {
|
|
invisiblePasscodeField = UITextField()
|
|
invisiblePasscodeField.keyboardType = .numberPad
|
|
invisiblePasscodeField.isSecureTextEntry = true
|
|
invisiblePasscodeField.delegate = self
|
|
invisiblePasscodeField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
|
|
view.addSubview(invisiblePasscodeField)
|
|
}
|
|
private func configureNavigationItems() {
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(title: R.string.localizable.cancel(), style: .plain, target: self, action: #selector(self.userTappedCancel))
|
|
}
|
|
private func configureLockView() {
|
|
lockView = LockView(model)
|
|
lockView.translatesAutoresizingMaskIntoConstraints = false
|
|
view.addSubview(lockView)
|
|
lockView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
|
|
lockView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
|
|
lockView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
|
|
lockView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
|
|
}
|
|
@objc func userTappedCancel() {
|
|
if let finish = willFinishWithResult {
|
|
finish(false)
|
|
}
|
|
dismiss(animated: true, completion: nil)
|
|
}
|
|
@objc func enteredPasscode(_ passcode: String) {
|
|
shouldIgnoreTextFieldDelegateCalls = false
|
|
clearPasscode()
|
|
}
|
|
func clearPasscode() {
|
|
invisiblePasscodeField.text = ""
|
|
for characterView in lockView.characters {
|
|
characterView.setEmpty(true)
|
|
}
|
|
}
|
|
func hideKeyboard() {
|
|
invisiblePasscodeField.resignFirstResponder()
|
|
}
|
|
func showKeyboard() {
|
|
invisiblePasscodeField.becomeFirstResponder()
|
|
}
|
|
func finish(withResult success: Bool, animated: Bool) {
|
|
invisiblePasscodeField.resignFirstResponder()
|
|
if let finish = willFinishWithResult {
|
|
finish(success)
|
|
} else {
|
|
dismiss(animated: true, completion: nil)
|
|
}
|
|
}
|
|
@objc func keyboardWillShow(_ notification: Notification) {
|
|
if let userInfo = notification.userInfo {
|
|
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
|
|
UIView.animate(withDuration: 0.1, animations: { () -> Void in
|
|
self.lockView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -keyboardSize.height).isActive = true
|
|
})
|
|
}
|
|
}
|
|
}
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
deinit {
|
|
NotificationCenter.default.removeObserver(self)
|
|
}
|
|
}
|
|
|
|
extension LockPasscodeViewController: UITextFieldDelegate {
|
|
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
|
if shouldIgnoreTextFieldDelegateCalls {
|
|
return false
|
|
}
|
|
let newString: String? = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
|
|
let newLength: Int = newString?.count ?? 0
|
|
if newLength > model.charCount() {
|
|
lockView.shake()
|
|
textField.text = ""
|
|
return false
|
|
} else {
|
|
for characterView in lockView.characters {
|
|
let index: Int = lockView.characters.index(of: characterView)!
|
|
characterView.setEmpty(index >= newLength)
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
@objc func textFieldDidChange(_ textField: UITextField) {
|
|
if shouldIgnoreTextFieldDelegateCalls {
|
|
return
|
|
}
|
|
let newString: String? = textField.text
|
|
let newLength: Int = newString?.count ?? 0
|
|
if newLength == model.charCount() {
|
|
shouldIgnoreTextFieldDelegateCalls = true
|
|
textField.text = ""
|
|
perform(#selector(self.enteredPasscode), with: newString, afterDelay: 0.3)
|
|
}
|
|
}
|
|
}
|
|
|