Before iOS 8, if you wanted to alert the user about something, you would use an UIAlertView like this:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Pre iOS 8 style" message:@"Old style alert" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; [alertView show];
In iOS 8, UIAlertView is deprecated. Instead we have a brand new and more flexible way to present alerts (and action sheets). It’s called UIAlertController. So let’s see how we would display a simple alert using this new controller.
let alert = UIAlertController(title: "New alert style", message: "This alert is displayed using a UIAlertController", preferredStyle: .Alert) let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel , handler: nil) alert.addAction(cancelAction) presentViewController(alert, animated: true, completion: nil)
This will display the following alert:
There are a few differences to the way we used to configure the UIAlertView. Let’s go over them. First we create an alert controller and give it a title, a message and a style. UIAlertController replaces UIAlertView and UIActionSheet classes, so we can choose what we want to display. You can also associate actions with your alert controller and give the user a way to respond. We have created only a cancel action, but you can create more than just one. The block based API is very handy. You just specify a block of code that will be executed when the user taps on the button corresponding to the action you’re specifying. We’ll see that in our next example.
And finally, showing the alert means that you need to present the alert controller, just like you would present any other view controller. Again, you can specify a block of code that can be executed on completion of presenting the controller. It’s not complicated, just different and much more flexible than before.
Let’s see another example where we customise the alert a bit more.
let alert = UIAlertController(title: "Feedback alert", message: "Update your feedback in the text field ", preferredStyle: .Alert) let deleteAction = UIAlertAction(title: "Delete", style: .Destructive , handler: nil) alert.addAction(deleteAction) alert.addTextFieldWithConfigurationHandler { (textField) -> Void in textField.placeholder = "Enter feedback" } let updateAction = UIAlertAction(title: "Update", style: .Default) { (action) -> Void in let feedbackTextField: UITextField = alert.textFields?.first as UITextField let text = feedbackTextField.text println("You have updated your feedback to: \(text)") } alert.addAction(updateAction) presentViewController(alert, animated: true, completion: nil)
This is how it will look:
let alert = UIAlertController(title: "Login", message: "Please enter your username and password", preferredStyle: .Alert) alert.addTextFieldWithConfigurationHandler { (textField) -> Void in textField.placeholder = "Enter username" } alert.addTextFieldWithConfigurationHandler { (textField) -> Void in textField.placeholder = "Enter password" textField.secureTextEntry = true } let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel , handler: nil) alert.addAction(cancelAction) let loginAction = UIAlertAction(title: "Login", style: .Default) { (action) -> Void in println("You have been logged in") } alert.addAction(loginAction) presentViewController(alert, animated: true, completion: nil)
It will look like this:
The code is very similar to the previous one. We add two text fields, one for the username and one for the password and we make sure that the password doesn’t show. This makes creating login dialogs very easy.
Action Sheet
The action sheet is used when we want to present the user with a set of choices. Unlike the alert, the action sheet is displayed differently on iPad and iPhone. On iPhone the action sheet will rise from the bottom of the screen. On iPad an action sheet will be displayed in a popover.
Let’s see an example where we display a simple action sheet:
let alert = UIAlertController(title: "Action Sheet", message: "Please choose an action", preferredStyle: .ActionSheet) let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel , handler: nil) alert.addAction(cancelAction) let deleteAction = UIAlertAction(title: "Delete", style: .Destructive , handler: nil) alert.addAction(deleteAction) let anotherAction = UIAlertAction(title: "Default option", style: .Default) { (alertAction) -> Void in println("done!") } alert.addAction(anotherAction) presentViewController(alert, animated: true, completion: nil)
As you can see, when creating the alert controller we need to specify that it’s going to be an action sheet. We create and add actions just the same as we’ve seen for alerts. We can’t add text fields to an action sheet, if you try you will get a runtime exception. The Cancel button, if present, will always be displayed at the bottom. The other buttons are displayed in the order of which the actions were added to the alert controller. You should add the destructive action first (delete, reset).
If you run this code on iPad it will crash.
Terminating app due to uncaught exception ‘NSGenericException’, reason: ‘Your application has presented a UIAlertController (<UIAlertController: 0x79672730>) of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller’s popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.’
The action sheet will be presented in a popover on iPad. A popover needs an anchor point and we are using a UIButton for this. We should use a UIBarButtonItem instead or we need to set a source view. The error is actually very helpful in this case. We can fix this by setting our button as the source view for the popover:
You will notice that the action sheet only has two actions, there is no Cancel button. We can easily get rid of the popover by tapping outside its area, so there is no need for a Cancel button.
Alerts and action sheets are just as easy to use in iOS 8 as they were before. You do have to write a bit more code but the flexibility you get for that is worth the trouble.