Uialertcontroller Changes in IOS 8

Source: Internet
Author: User
Tags compact

This article reprinted to http://www.th7.cn/Program/IOS/201409/276000.shtml

As part of the theme of IOS 8 to make interfaces adaptive there is some major changes to the presentation of view control Lers. The new Uipresentationcontroller does a lot of the hard work of the animating view controller transitions and adapting to Devi Ce size changes such as rotation. It also brings some big changes to some old UIKit favourites such as alert views, action sheets, popovers and search bar C Ontrollers. This post is a gentle introduction to this new world by looking at the changes to alert views and action sheets.

Uialertview-alerting the old

The last time I wrote on alert views is back in describe the Uialertview changes in IOS 5. The release of IOS 5 brought alert view styles but not much else have changed since then. The code snippet below is any it takes to setup and present a alert view with Cancel and OK buttons:

style"delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];[alertView show];

The introduction of Alert view styles in IOS 5 added a limited ability to create custom alerts by setting the Alertviewsty Le property. This extended the plain default button-only style to allow plain text input, secure text input or even a login and pas Sword Input Alert:

The Uialertviewdelegate protocol have callback methods for the button actions and also a method (Alertviewshouldenableother Button:) Called when a text field changes to allow buttons to be dynamically enabled/disabled.

Uialertcontroller-adaptive Alerting

In the new adaptive World IOS 8 The Uialertcontroller are a functionally identical, block-based replacement for both Uialertview and Uiactionsheet. Switching between an alert or action sheet was done by setting the preferred style when creating the controller.

A Simple Alert

It is interesting to compare the code required to setup a new style alert to the old Uialertview. The creation of the basic Uialertcontroller is very similar to creating an Uialertview (the Alerttitle and Alertmessage ar E both nsstring ' s):

UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:alertTitlemessage:alertMessagepreferredStyle:UIAlertControllerStyleAlert];

There is no delegate, nor does we initially specify the buttons. Note the third parameter which chooses between the alert and action sheet styles.

You add action buttons by creating a instance of Uialertaction which you then add to the controller. The uialertaction consists of a title string, style and a block to execute when the user selects the action. The three possible choices for the Uialertactionstyle cover default, cancel and destructive actions. To reproduce the classic Cancel/ok action sheet We just need to create and add the alert actions:

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action")style:UIAlertActionStyleCancelhandler:^(UIAlertAction *action){NSLog(@"Cancel action");}];UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK action")style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *action){NSLog(@"OK action");}];[alertController addAction:cancelAction];[alertController addAction:okAction];

Finally we can present the Alert view controller as with any other view controller:

[self presentViewController:alertController animated:YES completion:nil];

The display order for the buttons depends on the order they is added to the alert controller. If you follow the IOS Human Interface guidelines your should make the default action the right button and the Cancel button The left button for a, a, and a button alert. You can be only having one cancel action, if you add a second you'll get a runtime exception:

Terminating app due to uncaught exception ' nsinternalinconsistencyexception ', Reason: ' Uialertcontroller can only has One action with a style of Uialertactionstylecancel '

Destructive actions

Here are a quick example of the third alert action style for destructive actions. The code is the same as before except that we add a "reset" button instead of the "OK" button:

style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { NSLog(@"Reset action"); }];[alertController addAction:resetAction];[alertController addAction:cancelAction];[self presentViewController:alertController animated:YES completion:nil];

Note that this time the destructive action was added first to make it appear on the left.

Text Input Alerts

The greater flexibility of the uialertcontroller means so you no longer need to be constrained by the built-in styles fo R plain Text, secure text or login and password input alert views. We can add an arbitrary number of Uitextfield objects to the alert and use all of the standard Uitextfield configuration O Ptions. When you add the text field to the alert controller, you specify a block, that's used to configure the text field.

For example, to recreate the old login and password style alert We can add both text fields and configure them with the Appropriate placeholder text and set the password field to use secure text entry:

UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:alertTitle message:alertMessagepreferredStyle:UIAlertControllerStyleAlert];[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.placeholder = NSLocalizedString(@"LoginPlaceholder", @"Login"); }];[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.placeholder = NSLocalizedString(@"PasswordPlaceholder", @"Password"); textField.secureTextEntry = YES; }];

The values of the text field can be retrieved in the OK action handler:

UIAlertAction *okAction = [UIAlertActionactionWithTitle:NSLocalizedString(@"OK", @"OK action")style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *action){UITextField *login = alertController.textFields.firstObject;UITextField *password = alertController.textFields.lastObject;...}];

Things get a little more complicated if we want to reproduce the behaviour of the old Uialertview delegate method alertViewShouldEnableOtherButton: . Assume we only want to enable the OK button if the user have entered at least 3 characters in the login field. There is no equivalent delegate method for Uialertcontroller so we need to add a observer to the Login text field. We can do and the following code snippet in the configuration block:

[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {...[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(alertTextFieldDidChange:)name:UITextFieldTextDidChangeNotificationobject:textField]; }];

We need to remove the observer when the view Controller was dismissed by adding the appropriate code to the handler Blo CK for each of the actions (and anywhere else we may dismiss the alert controller). For example in the Okaction block we saw earlier:

UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK action")style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *action){...[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];}];

Before presenting the alert controller we can disable the OK action:

okAction.enabled = NO;

Then on the notification observer we can check the login text field for content before changing the state back to Enabled:

- (void)alertTextFieldDidChange:(NSNotification *)notification{UIAlertController *alertController = (UIAlertController *)self.presentedViewController;if (alertController){UITextField *login = alertController.textFields.firstObject;UIAlertAction *okAction = alertController.actions.lastObject;okAction.enabled = login.text.length > 2;}}

The alert view is now presented with the OK button disabled unless there be at least three characters in the login text F Ield:

Action Sheet

The action sheet is used if you need to present the user with a set of choices. Unlike the alert view which is all presented as a modal view the presentation of the action sheet depends on the device Size. On a iPhone (compact width) The action sheet rises from the bottom of the. On the IPad (regular width) an action sheet are always shown in a popover.

The creation of an action sheet was almost identical to a alert, the only difference being the style:

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alertTitlemessage:alertMessage preferredStyle:UIAlertControllerStyleAlert];

You add actions the same-a-alerts so I'll abbreviate the code to add three actions:

UIAlertAction *cancelAction = ...;// UIAlertActionStyleCancelUIAlertAction *deleteAction = ...;// UIAlertActionStyleDestructiveUIAlertAction *archiveAction = ...; // UIAlertActionStyleDefault[alertController addAction:cancelAction];[alertController addAction:deleteAction];[alertController addAction:archiveAction];

You cannot add the text fields to action sheets, if you try it get a runtime exception:

Terminating app due to uncaught exception ' nsinternalinconsistencyexception ', Reason: ' Text fields can is only added T o an alert controller of style Uialertcontrollerstylealert '

If We do nothing more and present the iphone/compact width device it works as expected:

[self presentViewController:alertController animated:YES completion:nil];

The Cancel button, if present, is all shown as the bottom of the view regardless of the order it was added to the alert Controller. The other actions is shown top to bottom in the order they were added. The IOS Human Interface guidelines recommend that any destructive action is shown first.

There is a problem with this code when used on an IPAD or regular width device it creates a runtime exception:

Terminating app due to uncaught exception ' nsgenericexception ', Reason: ' Uipopoverpresentationcontroller (<_ uialertcontrolleractionsheetregularpresentationcontroller:0x7fc619588110>) should have a non-nil sourceView or Barbuttonitem set before the presentation occurs. '

At the time of writing the Apple Uicatalog sample code crashes for the same reason when run on an iPad.

As I mentioned before for regular width presentations The action sheet are displayed in a popover. A popover requires a anchor point which can is a source view or a bar button item. In this case I am using a, UIButton to trigger the action sheet so I'll use it as the anchor point.

A big difference in IOS 8 is, we no longer need to write code to test for the interface idiom. The Uialertcontroller takes care of adapting to the display environment so we can simply ask it for a popover controller. On a iphone/compact width device this returns nil. The extra code we need to configure the popover is below:

UIPopoverPresentationController *popover = alertController.popoverPresentationController;if (popover){popover.sourceView = sender;popover.sourceRect = sender.bounds;popover.permittedArrowDirections = UIPopoverArrowDirectionAny;}

The Uipopoverpresentationcontroller class is also new on IOS 8 and replaces Uipopovercontroller and for we purposes is FU nctionally equivalent. The action sheet now displays as a popover anchored to the source button:

Note that the Uialertcontroller are also smart enough to remove the Cancel button when using a popover. A user cancels a popover by touching outside of the popover so it's not required.

Dismissing Alert Controllers

Typically the alert controller is a dismissed automatically when the user selects an action. It can also be dismissed programmatically, if required, as any other view controller. One common reason can is to remove the alert or action sheet when the app moves to the background. Assuming we is listening for the UIApplicationDidEnterBackgroundNotification notification we can dismiss any presented view controller in the observer (see the Example code for the setup of the Observer in Viewdidload):

- (void)didEnterBackground:(NSNotification *)notification{[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotificationobject:nil];[self.presentedViewController dismissViewControllerAnimated:NO completion:nil];}

Note this to is safe we also make sure to remove any text field observers we may have added to the alert controller.

In Summary

A Long Post But hopefully it'll be another three years before I need to write about alert and action sheets again. The old Uialertview and Uiactionsheet classes still work fine in iOS 8 so if you need to target iOS 7 there are no rush to Migrate immediately. The Alertcontroller sample Xcode project for this post can be found in my GitHub codeexamples repository.

Uialertcontroller Changes in IOS 8

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.