Reputation: 2210
In my UIViewController
subclass I created a UIAlertController
with a UITextField
:
class MyViewController: UIViewController {
...
let alertController = UIAlertController(title: "a title", message: "", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK!", style: .default) { alert in
print("OK!!")
}
alertController.addTextField { (textField) in
textField.placeholder = "a placeholder"
textField.delegate = self
}
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
...
}
extension MyViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
return true
}
}
Now, when alert is shown and I tap keyboard next/done button, the keyboard and the alert are dismissed and OK! is printed.
In my textFieldShouldReturn
method there are neither textField.resignFirstResponder()
nor alert dismiss command, so how it's possible that keyboard and alert is dismissed? How Apple achieves this behaviour? Has textField
two delegates?
Upvotes: 1
Views: 1069
Reputation: 889
As matt already mentioned, that behavior is normal for alerts including a textField.
Once you hit the return-key on the keyboard it triggers .editingDidEndOnExit
and that will dismiss the keyboard and the alert.
You can prevent that behavior by just removing the target on the textField like this:
textField.removeTarget(nil, action: nil, for: .editingDidEndOnExit)
This will not dismiss the alert anymore once you tap the return-key on the keyboard.
Upvotes: 1
Reputation: 2210
I wanted to understand Apple UIAlertController
behavior to add the same behavior in my alert custom controller that I'm implementing. With @matt's answer help, I think I figured out how UIAlertController
works. Below my code snippet to connect all alert's textfields:
guard let last = textFields.last else {
return
}
for i in 0 ..< textFields.count - 1 {
textFields[i].returnKeyType = .next
textFields[i].addTarget(textFields[i+1], action: #selector(UIResponder.becomeFirstResponder), for: .editingDidEndOnExit)
}
last.returnKeyType = .done
last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)
In this way when I tap on keyboard next/done button and the last textfield is the first responder, keyboard is dismissed; otherwise next textfield becomes the first responder.
This post has helped too.
Upvotes: 0
Reputation: 535138
Actually, you're not putting the question strongly enough. You can delete your extension and the line textField.delegate = self
, and the alert will still dismiss when the user hits Return.
That behavior is automatic for an alert. Unless you disable the dismiss button, it is tapped for you by default when the user hits Return in the virtual keyboard.
As for the actual mechanism, it's an editingDidEndOnExit
control event. This leaves you free to set a delegate without messing things up.
Upvotes: 2