Prevent dismissal of UIAlertController

You’re correct: if the user can tap a button in your alert, the alert will be dismissed. So you want to prevent the user from tapping the button! It’s all just a matter of disabling your UIAlertAction buttons. If an alert action is disabled, the user can’t tap it to dismiss.

To combine this with text field validation, use a text field delegate method or action method (configured in the text field’s configuration handler when you create it) to enable/disable the UIAlertActions appropriately depending on what text has (or hasn’t) been entered.

Here’s an example. We created the text field like this:

alert.addTextFieldWithConfigurationHandler {
    (tf:UITextField!) in
    tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
}

We have a Cancel action and an OK action, and we brought the OK action into the world disabled:

(alert.actions[1] as UIAlertAction).enabled = false

Subsequently, the user can’t tap OK unless there is some actual text in the text field:

func textChanged(sender:AnyObject) {
    let tf = sender as UITextField
    var resp : UIResponder = tf
    while !(resp is UIAlertController) { resp = resp.nextResponder() }
    let alert = resp as UIAlertController
    (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
}

EDIT Here’s the current (Swift 3.0.1 and later) version of the above code:

alert.addTextField { tf in
    tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
}

and

alert.actions[1].isEnabled = false

and

@objc func textChanged(_ sender: Any) {
    let tf = sender as! UITextField
    var resp : UIResponder! = tf
    while !(resp is UIAlertController) { resp = resp.next }
    let alert = resp as! UIAlertController
    alert.actions[1].isEnabled = (tf.text != "")
}

Leave a Comment