UIAlterController使用

前两天加了一个actionSheet,忘记针对iPad适配,导致悲剧了😭,今天顺便就在复习一下。

自iOS 8开始,UIAlertController就取代了UIAlertView和UIAlertSheet。

创建一个demo看看

1 简单的对话框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)showAlertView
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"demo" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"OK Action");
}];
UIAlertAction *warningAction = [UIAlertAction actionWithTitle:@"warning" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"warning Action");
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Cancel Action");
}];
[alertController addAction:okAction];
[alertController addAction:warningAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}

alert.png

2 ActionSheet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)showAlertView
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"demo" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"OK Action");
}];
UIAlertAction *warningAction = [UIAlertAction actionWithTitle:@"warning" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"warning Action");
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Cancel Action");
}];
[alertController addAction:okAction];
[alertController addAction:warningAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}

actionSheet.png

这里的preferredStyle:参数是UIAlertControllerStyleActionSheet,如果Action Sheet中有取消按钮,取消按钮每次都会在底部显示,其他按钮会按照添加的顺序显示。在Action Sheet内不能添加文本框。如果你添加了文本框,在运行时会抛出下面的异常提醒:

* Terminating app due to uncaught exception
‘NSInternalInconsistencyException’, reason: ‘Text fields can only be added to an alert controller of style UIAlertControllerStyleAlert’

##如上面说到的,在iPad中ActionSheet以弹出框的形式呈现,如果还是按照上面写就会崩溃。iPad弹出弹出框总是需要一个锚点,锚点可以是源视图,也可以是按钮。需要添加一下代码:

1
2
alertController.popoverPresentationController.sourceView = self.view;
alertController.popoverPresentationController.sourceRect = self.view.bounds;

3 退出警告控制器

警报控制器会在用户点击按钮后自动消失,但在app进入后台时,警告框和选择表并不会自动退出。此时,我们需要通过代码实现退出警报控制器。

在通知中心进行注册,当接收到app进入后台的通知时退出警报控制器。更新后的viewDidLoad如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)viewDidLoad
{
[super viewDidLoad];
// app 进入后台后隐藏警报控制器
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}];
}
- (void)dealloc
{
// 移除观察者
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}

最后一定记得移除观察者,否则会引起崩溃。

总结

  • AlertView
    • 一般显示在当前视图控制器的中心,点击警告框以外区域不能隐藏警告控制器。
    • 可以添加任意数量文本框。
    • 有一个或两个按钮时,横向排布,如果有Cancel按钮,则Cancel按钮显示在左侧;有两个以上按钮时,竖列排布,如果有Cancel按钮,则Cancel按钮显示在最底部。其他按钮按照添加顺序排布。
  • ActionSheet
    • 在iPhone中自下而上滑出显示在当前控制器的底部,点击action sheet以外区域可以隐藏UIAlertController。
    • 在iPad中以popover方式、以源视图为锚点显示,点击选择表以外的区域可以隐藏警告控制器。
    • 不能添加文本框。
    • 按钮竖列排布,在iPhone中,Cancel按钮默认在底部显示;在iPad中,Cancel按钮默认不显示