UIAlertController in iOS 8

If you’ve developed for iOS in the past using Objective – C, you’ll remember creating alert views and action sheets using the UIAlertView and UIActionSheet classes. In iOS 8, these classes have been deprecated in favor of the new UIAlertController class. In this blog, we’ll take a look at how to present both alerts and action sheets with UIAlertController. The code example for this blog can be downloaded here: AlertControllerDemo.

The UIAlertController class is very simple to configure and use. We create a new alert view controller by instantiating it with the constructor UIAlertController(title: String, message: String, preferredStyle: UIAlertControllerStyle). The UIAlertControllerStyle property may be either .Alert or .ActionSheet, so to instantiate a new alert controller as an alert view we would do something like this:

let alert = UIAlertController(
            title: "Take action!",
            message: "Enter some text and hit OK, or Cancel",
            preferredStyle: UIAlertControllerStyle.Alert)

Making a new action sheet is just as simple: just set the preferredStyle parameter to UIAlertControllerStyle.ActionSheet.

Of course, an alert doesn’t do much good if we don’t give the user a way to respond. In UIAlertController, these responses take the form of UIAlertActions. We add a UIAlertAction by calling its initializer: UIAlertAction(title: String, style: UIAlertActionStyle, handler: ((UIAlertAction!) -> Void)!). The style parameter may be one of:

  • .Default – the default style for a UIButton
  • .Cancel – similar to .Default, but with bolded text
  • .Destructive – text is emphasized to indicate to the user that responding in this way may make a non-reversible change.

These styles change the appearance of the UIAlertAction’s button only; there is nothing inherently destructive about using the .Destructive style. You might use it if you wanted to warn the user they were about to delete a file, for example.

The handler parameter is a closure that takes a UIAlertAction and returns nothing, If we pass nil here, the alert will be dismissed when the action button is clicked. This is the kind of default action we want to take with a Cancel button, for example. We can also write code in the handler to take an action when the user presses the button. For example, in the sample code accompanying this blog, we use an action sheet to present three buttons (as UIAlertActions) to change the color of a subview either red, blue, or white depending on the button clicked. The UIAlertAction code for the blue button looks like this:

      title: "Blue",
      style: UIAlertActionStyle.Default,
      handler: { (UIAlertAction) -> Void in
          self.subView.backgroundColor = UIColor.blueColor()

The .addAction method of the UIAlertController adds an action button to the view (in this case, an .ActionSheet style alert controller called actionSheet). We can’t infer self from inside a closure; we have to call it out explicitly as shown in the line

self.subView.backgroundColor = UIColor.blueColor()

With the ActionSheet style, we only have the option of presenting buttons to the user. But with the Alert style, we can also present a text field to the user and collect information from them inside the alert controller itself. In the sample code, we get a string from the user and present it in a UILabel using a text field control inside an .Alert style UIAlertController. The code for this alert controller is below:

@IBAction func btnAlertClicked(sender:UIButton) {
        //an alert view:
        let alert = UIAlertController(
            title: "Take action!",
            message: "Enter some text and hit OK, or Cancel",
            preferredStyle: UIAlertControllerStyle.Alert)

        //add a text field:

        //first action copies the text field text to a UILabel:
            title: "OK",
            style: UIAlertActionStyle.Default,
            handler: { (UIAlertAction) - > Void in
                    The textFields array is of type [AnyObject]?
                    Unwrap it, then index into it. Cast the result
                    as a text field, and assign its text property to
                    the UILabel:
                self.lbText.text = (alert.textFields![0] as UITextField).text

        //second action cancels the alert view:
            title: "Cancel",
            style: UIAlertActionStyle.Cancel,
            handler: nil

        //present the alert:
        presentViewController(alert, animated: true, completion: nil)

The .addTextFieldWithConfigurationHandler method puts a text field in the alert controller’s view. The configuration handler may be used to set properties of the text view; normally this is not necessary in an alert, but the closure signature to use here is ((UITextField!) -> Void)! . Passing nil here gives us a default text field.

The text fields are placed in an array called textFields. This is an array of AnyObject optionals, so to get the text out of a text field (after indexing into the array), we first must unwrap the optional, then cast the result as a UITextField, and finally use its text property. This is shown in the example above.

Alerts and text fields are displayed in the order they are added to the UIAlertController object. After adding all the buttons and text fields you wish to display, present the alert controller by using method:

viewControllerToPresent: UIViewController,
animated: Bool,
completion: (() -> Void)? )

This is shown in the example above. The completion closure will be fired when the alert controller is dismissed in any way. One thing to note here is that all action buttons on an alert controller’s view will dismiss the alert controller! This makes sense… The user is presented with a limited number of choices and must select only one from the list. Of course, entering text into a text field doesn’t dismiss the controller, only tapping a button does.

Explore the attached code, and have fun with the new UIAlertController class!

Screen Shot 2014-12-10 at 9.37.31 AM

Screen Shot 2014-12-10 at 9.39.36 AM

Leave a Comment: