Search code examples
iosuialertcontrolleruitextfielddelegateresignfirstresponder

UIAlertController with textfield: how dismiss keyboard works?


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?


Solution

  • 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.