由起
UIAlertController
是iOS8中引入的,用于整合UIAlertView
和UIActionSheet
的新类,在实现中抛弃了之前的delegate用法,而采用了block的方式,从而使得使用和可读性都简化了不少。
使用iOS8SDK编译的项目,大多数情况使用之前的UIAlertView
或UIActionSheet
都不会产生问题,如果有问题了,那就需要使用新类了。比如,一个项目中iPad上调用[actionSheet showFromToolbar:]
产生错误:
2014-11-05 10:50:26.614 XXXXXX[467:78104] Presenting view controllers on detached view controllers is discouraged <UIViewController: 0x17ea3470>.
2014-11-05 10:50:26.762 XXXXXX[467:78104] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0x17e73620>) 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.'
从奔溃日志中可以看出,虽然代码中使用的是UIActionSheet
,实际运行时却已经是UIAlertController
了。
使用
使用非常简单,基本用法:
//初始化alert controller
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:ZJLocalizedString(@"xxxx") message:nil preferredStyle:UIAlertControllerStyleActionSheet];
//创建一个操作
UIAlertAction *fileAction = [UIAlertAction actionWithTitle:ZJLocalizedString(@"action1") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self doAction1];
}];
//添加操作
[alertController addAction:fileAction];
//
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:ZJLocalizedString(@"Cancel") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
}];
[alertController addAction:cancelAction];
//展示alert controller
[self presentViewController:alertController animated:YES completion:^{
}];
初始化controller的时候,通过UIAlertActionStyle
来选择哪种式样,然后就创建一系列action,并添加到controller,最后把controller用present的方式展示出来。对于以前alert上带文字的式样,新API也贴心的提供了addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler
方法来简化操作。
可见,新API最大的特点无疑就是吸取了开源社区中已有的block的实现,这样最大限度的简化了代码,并且带来了无与伦比的可读性。由于新API中action的初始化是类方法,如果action不作为类成员的话,也不需要考虑block的循环引用问题。
结束
iOS8对API的更新还是挺大的,比如UIPopoverViewController
兼容iPad和iPhone,所以可以慢慢的开始更新了。
紧急修正
经过测试,在ipad上的使用还需要注意一个问题,那就是在present之前要设置UIAlertController
的属性popoverPresentationController
。该属性是UIPopoverPresentationController
类,主要用途就是管理popover中的内容。如果不设置,在iPad竖屏测试的时候没有问题,但是在横屏的时候就会有问题。原因在于,横屏的时候,popover没有指定位置。这时,可以
UIPopoverPresentationController *popoverPresentationController = alertController.popoverPresentationController;
popoverPresentationController.barButtonItem = (UIBarButtonItem *)sender;
//或
popoverPresentationController.sourceView = (UIButton *)sender;
popoverPresentationController.sourceRect = [(UIButton *)sender bounds];
Comments