How to create alert views and action sheets in iOS 8

Screen Shot 2015 09 28 at 23 37 12

Up until iOS 7 we could use the UIAlertView and UIActionSheet classes to bring up alerts and action sheets respectively. As of iOS 8 those classes are deprecated. Although they still work, we’re encouraged to use the UIActionController class instead. Here’s how to use it.

The main difference is that both of the old classes have been converged into one, so now we simply tell the alert controller how we want to bring up the information.

While the old classes used a delegate protocol so we could react to the outcome of user interactions, the UIActionController class uses completion blocks, making our coding efforts a little easier. All we have to do is create an action, specify things like title, subtitle and appearance, and add a block that shall be executed upon completion.

Here are three examples.

Creating a standard Alert View

- (IBAction)showAlert {
    
    // create an alert controller with the appearance of an alert view
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Attention" message:@"This looks just like the old UIAlertView, doesn't it?" preferredStyle:UIAlertControllerStyleAlert];
    
    // create the actions handled by each button
    UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"Defo!" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"User said DEFO!");
    }];
    
    UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"Never!" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"User said NEVER!");
    }];
    
    // add actions to our alert
    [alert addAction:action1];
    [alert addAction:action2];
    
    // display the alert controller
    [self presentViewController:alert animated:YES completion:nil];
}

In the above method we create an action controller with its dedicated init method, which lets us specify a title, subtitle and a preferred style. We have a choice of UIAlertControllerStyleAlert, or if we wanted to create an action sheet, UIAlertControllerStyleActionSheet (see below).

Next we create two actions, each of which represents a button that will be added to the controller. Add as many as you like, just like with the old UIAlertView: one or two buttons will be shown next to each other, while more than three will appear stacked on top of each other.

We add all our actions to the alert controller using the addAction method, and then present it via our view controller’s presentViewController method.

If you like you can add all actions to an array and pass the whole array to the actions property of the UIAlertController.

Creating an Alert View with Text Input

New in this class is the option to add a text field to the alert so we can process user input. This used to be a little bit “advanced” shall we say, and it’s much easier now. Here’s what this looks like:

Screen Shot 2015 09 29 at 00 13 53

And here’s how to do it:

@property (nonatomic, strong) UIAlertController *alertWithText;

// ...

- (IBAction)showAlertWithTextInput:(id)sender {
    
    // display the alert controller
    [self presentViewController:self.alertWithText animated:YES completion:nil];
}

- (UIAlertController *)alertWithText {
    
    if (!_alertWithText) {
        
        // create an alert controller
        _alertWithText = [UIAlertController alertControllerWithTitle:@"Tell me something" message:@"Give me your phone number so I can call you thirtyseven times every day." preferredStyle:UIAlertControllerStyleAlert];
        
        // create the actions handled by each button
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSLog(@"User chose OK");
            NSLog(@"User Input was %@", [self accessAlertTextField]);
        }];
        
        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
            NSLog(@"User chose CANCEL (and we don't want to know what the input was)");
        }];
        
        // add the actions to our alert
        [_alertWithText addAction:action1];
        [_alertWithText addAction:action2];
        
        // add a text field
        [_alertWithText addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            
            // pre-populate the text field and properties
            textField.text = @"(646) 401-0937";
            textField.keyboardType = UIKeyboardTypePhonePad;
            textField.keyboardAppearance = UIKeyboardAppearanceDark;
        }];
    }
    return _alertWithText;
}

- (NSString *)accessAlertTextField {
    
    return [self.alertWithText.textFields lastObject].text;
}

There are two parts to this: first we have the method that brings up the alert view, and second is a custom initialiser for the alert controller. We’ll do it this way because in order to read out the text field, we need a reference – hence a property is needed for the controller.

Our initialiser creates the alert controller much like we did above, but we’ll also add a text field using the addTextFieldWithConfigurationHandler method. This allows us to propagate and manipulate the text field before it’s put on screen.

The initialiser is called just before we try to present the controller. Thanks to our property we have a reference to the alert controller, so we can read out the text field. Nice!

Creating an Action Sheet

And finally, here’s how we create an action sheet. It works exactly like the alert view we’ve created above, with the exception that you cannot have a text field in this type of presentation. This is what it looks like:

Screen Shot 2015 09 28 at 23 37 26

And here’s how to do it in code:

- (IBAction)showActionSheet:(id)sender {
    
    // create an alert controller with action sheet appearance
    UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:@"Blimey, Guvna!" message:@"This looks just like the old UIActionSheet, doesn't it?" preferredStyle:UIAlertControllerStyleActionSheet];
    
    // create the actions handled by each button
    UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"Defo!" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"User said DEFO!");
    }];
    
    UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"Never!" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"User said NEVER!");
    }];
    
    // add actions to our sheet
    [actionSheet addAction:action1];
    [actionSheet addAction:action2];
    
    // bring up the action sheet
    [self presentViewController:actionSheet animated:YES completion:nil];
}

Demo Project and Further Reading





5 thoughts on “How to create alert views and action sheets in iOS 8

  1. Thank you for the tutorial. For me just one important thing is missing though: how do I “add a block that shall be executed upon completion.” ? The example code doesn’t actually do anything, and thus I am wondering.

    Thanks
    Toby

    1. Hi Toby, well the example code prints a log message – that happens inside the block (it’s part of the method signature, starts with the caret symbol, and ends with the square bracket). You can call anything you like in there, your own methods, or several hundred lines of code.

  2. Hi Jay, thank you very much for the explanation. I did see the NSLog, but I didn’t realize that that *was* the block. It’s clear now! -Toby

  3. That couldn’t be clearer. Thanks.

    I have a problem though. I have been stuck for weeks and have lost counts of the youtube videos I have watched to try to get help. When I implement your code I have no difficulty making it work to an extent.

    Whether I go for the Standard Alert view or the Action Sheet view it looks ok. The buttons appear so I assume I successfully added the actions, and the text I used for the titles appears on the buttons. But when I click the buttons nothing happen. In the action blocks I just put some NSLog statements. They do no appear and the Alert Controller does not appear. I have to restart the app.

    Any idea what I am doing wrong? It is driving me mad. I am using Xcode 7 and my mac has OS 10. I am running my app in the simulator.

    1. Not without seeing your code I’m afraid. Could you post a link to your project? If you upload it to GitHub I can offer a pull request (provided I figure out what the problem is).

Leave a Reply