An advanced Ethereum/EVM mobile wallet
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.
 
 
 
alpha-wallet-ios/Trust/Lock/ViewControllers/LockPasscodeViewController....

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)
}
}
}