Problem
I’m refactoring some “old” Swift code using deprecated UIAlertView
and delegates.
I have a UIAlertController
with an input textfield inside (and two buttons, OK and CANCEL). The user should insert his email address, then I should validate it anytime he enters a character: when the mail address is valid, the UIAlertController
button is enabled, else is disabled.
I got this code perfectly working but for some reason I’m not very happy with this solution. Is there something you would change?
var alertTextField: UITextField!
func textFieldDidChange(){
if let e = alertTextField.text {
let alertButton = alertController.actions[0]
alertButton.isEnabled = !Utils.isValidEmail(testStr: e) ? false : true
}
}
var alertController = UIAlertController(title: "Insert your email", message: "message", preferredStyle: .alert)
@IBAction func passwordForgot(_ sender: Any) {
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
print("Ok Button was Pressed")
})
ok.isEnabled = false
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
print("Cancel Button was Pressed")
}
alertController.addAction(ok)
alertController.addAction(cancel)
alertController.addTextField { (textField) -> Void in
self.alertTextField = textField
self.alertTextField?.placeholder = "mail"
textField.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControlEvents.editingChanged)
}
self.present(alertController, animated: true, completion: nil)
}
Solution
I would change this:
alertButton.isEnabled = !Utils.isValidEmail(testStr: e) ? false : true
to this one:
alertButton.isEnabled = Utils.isValidEmail(testStr: e)
The aspect of it that I’d change is having to store the alertController as a property. This adds state to your class that will be stale when the alert is done unless you add more code to clear it. And you can get it from somewhere else.
Here’s another way to implement the textFieldDidChange
method that doesn’t require the state:
@objc func textFieldDidChange(_ sender: UITextField) {
guard let alertController = presentedViewController as? UIAlertController else {
return
}
guard let alertButton = alertController.actions[0] else {
return
}
if let e = sender.text {
alertButton.isEnabled = Utils.isValidEmail(testStr: e)
}
}