UIAlertController【对话框】

来源:互联网 发布:江苏甲子网络 编辑:程序博客网 时间:2024/05/21 09:41

UIAlertController

在iOS 8中,UIAlertController在功能上是和UIAlertView以及UIActionSheet相同的,UIAlertController以一种模块化替换的方式来代替这两个类的功能和作用。

最基础的对话框

创建对话框视图控制器

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:<#(NSString *)#> message:<#(NSString *)#> preferredStyle:<#(UIAlertControllerStyle)#>]
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"这个是UIAlertController的标准样式" preferredStyle:UIAlertControllerStyleAlert];

要特别注意第三个参数,确定选择的是对话框样式(alert)还是上拉菜单样式(action sheet)。
UIAlertControllerStyle有两个枚举常量:

  • UIAlertControllerStyleActionSheet (上拉菜单样式)
  • UIAlertControllerStyleAlert (对话框样式)

显示对话框视图控制器

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

效果演示

这里写图片描述


动作按钮添加到控制器

[UIAlertAction actionWithTitle:<#(NSString *)#> style:<#(UIAlertActionStyle)#> handler:<#^(UIAlertAction * _Nonnull action)handler#>]

可以将动作按钮添加到控制器上。UIAlertAction由【标题字符串】、【样式】以及 【 当用户选中该动作时运行的代码块 】组成。通过UIAlertActionStyle,可以选择如下三种动作样式:【常规(default)】、【取消(cancel)】以及【警示(destruective)】。为了实现原来我们在创建UIAlertView时创建的按钮效果,我们只需创建动作按钮并将它们添加到控制器上即可。

UIAlertAction *cancerAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];[alertController addAction:cancerAction];[alertController addAction:okAction];
  • 按钮显示的次序取决于它们添加到对话框控制器上的次序。一般来说,在拥有两个按钮的对话框中,您应当将取消按钮放在左边。要注意,取消按钮是唯一的,如果您添加了第二个取消按钮,那么你就会得到如下的一个运行时异常:
    Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘UIAlertController can only have one action with a style of UIAlertActionStyleCancel’
  • “警示”样式: 按钮变成了红色。根据苹果官方的定义,“警示”样式的按钮是用在可能会改变或删除数据的操作上。因此用了红色的醒目标识来警示用户。

效果演示

这里写图片描述


添加文本对话框

UIAlertController非常灵活性,可以向对话框中添加任意数目的UITextField对象,并且可以使用所有的UITextField特性。当向对话框控制器中添加文本框时,需要指定一个用来配置文本框的代码块。

举个例子,要建立包含账号和密码样式对话框,我们可以向其中添加两个文本框,然后用合适的占位符来配置它们,将密码输入框设置使用安全文本输入,在“登陆”按钮按下时,我们让程序读取文本框中的值,并输出。

#import "ViewController.h"@interface ViewController ()@property(strong,nonatomic) UIButton *button;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, [[UIScreen mainScreen] bounds].size.width, 20)];    [self.button setTitle:@"跳转" forState:UIControlStateNormal];    [self.button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];    [self.view addSubview:self.button];    [self.button addTarget:self action:@selector(clickMe:) forControlEvents:UIControlEventTouchUpInside];}-(void)clickMe:(id)sender{    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"文本对话框" message:@"包含账号和密码对话框示例" preferredStyle:UIAlertControllerStyleAlert];    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {        textField.placeholder = @"账号";    }];    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {        textField.placeholder = @"密码";        textField.secureTextEntry = YES;    }];    // 控制器上添加登陆按钮,在“登陆”按钮按下时,我们让程序读取文本框中的值,并输出    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"登陆" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {        UITextField *login = alertController.textFields.firstObject;        UITextField *password = alertController.textFields.lastObject;        NSLog(@"用户名 = %@,密码 = %@",login.text, password.text);    }];    [alertController addAction:okAction];    // 控制器上添加取消按钮    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];    [alertController addAction:cancelAction];    [self presentViewController:alertController animated:YES completion:nil];   }@end

效果展示

这里写图片描述


完善文本对话框

要实现让”账号”文本框中至少有3个字符才能激活“登陆”按钮。

  • 在UIAlertController中并没有相应的方法,因此我们需要向“账号”文本框中添加一个Observer。Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。我们可以在构造代码块中添加如下的代码片段来实现。
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {    textField.placeholder = @"账号";    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertTextFieldDidChange:) name:UITextFieldTextDidChangeNotification object:textField];}];[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {    textField.placeholder = @"密码";    textField.secureTextEntry = YES;}];
  • 当视图控制器释放的时候我们需要移除这个Observer,我们通过在每个按钮动作的handler代码块(还有其他任何可能释放视图控制器的地方)中添加合适的代码来实现它。比如说在okAction这个按钮动作中:
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"登陆" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {    UITextField *login = alertController.textFields.firstObject;    UITextField *password = alertController.textFields.lastObject;    NSLog(@"用户名 = %@,密码 = %@",login.text, password.text);    // 视图控制器释放的时候我们需要移除这个Observer    [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidEndEditingNotification object:nil];}];
  • 在显示对话框之前,我们要冻结“登陆”按钮
okAction.enabled = NO;
  • 在激活按钮状态前检查“登录”文本框的内容
- (void)alertTextFieldDidChange:(NSNotification *)notification{    UIAlertController *alertController = (UIAlertController *)self.presentedViewController;    if (alertController){        UITextField *login = alertController.textFields.firstObject;        UIAlertAction *loginAction = alertController.actions.lastObject;        loginAction.enabled = login.text.length > 2;    }}

完整代码

#import "ViewController.h"@interface ViewController ()@property(strong,nonatomic) UIButton *button;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, [[UIScreen mainScreen] bounds].size.width, 20)];    [self.button setTitle:@"跳转" forState:UIControlStateNormal];    [self.button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];    [self.view addSubview:self.button];    [self.button addTarget:self action:@selector(clickMe:) forControlEvents:UIControlEventTouchUpInside];}-(void)clickMe:(id)sender{    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"文本对话框" message:@"包含账号和密码对话框示例" preferredStyle:UIAlertControllerStyleAlert];    // 1.创建账号文本框,向登录文本框中添加一个Observer    [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {        textField.placeholder = @"账号";        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertTextFieldDidChange:) name:UITextFieldTextDidChangeNotification object:textField];    }];    [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {        textField.placeholder = @"密码";        textField.secureTextEntry = YES;    }];    // 2.创建取消按钮    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];    }];    // 3.创建登陆按钮,在“登陆”按钮按下时,我们让程序读取文本框中的值,并输出    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"登陆" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {        UITextField *login = alertController.textFields.firstObject;        UITextField *password = alertController.textFields.lastObject;        NSLog(@"用户名 = %@,密码 = %@",login.text, password.text);        // 视图控制器释放的时候我们需要移除这个Observer        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidEndEditingNotification object:nil];    }];    // 4.冻结“登陆”按钮    okAction.enabled = NO;    // 5.添加取消按钮和登陆按钮    [alertController addAction:cancelAction];    [alertController addAction:okAction];    [self presentViewController:alertController animated:YES completion:nil];}// 在激活按钮状态前检查“登录”文本框的内容- (void)alertTextFieldDidChange:(NSNotification *)notification{    UIAlertController *alertController = (UIAlertController *)self.presentedViewController;    if (alertController){        UITextField *login = alertController.textFields.firstObject;        UIAlertAction *loginAction = alertController.actions.lastObject;        loginAction.enabled = login.text.length > 2;    }}@end

效果展示

这里写图片描述 这里写图片描述


上拉菜单

当需要给用户展示一系列选择的时候,上拉菜单就能够派上大用场了。和对话框不同,上拉菜单的展示形式和设备大小有关。在iPhone上(紧缩宽度),上拉菜单从屏幕底部升起。在iPad上(常规宽度),上拉菜单以弹出框的形式展现。

创建上拉菜单的方式和创建对话框的方式非常类似,唯一的区别是它们的形式。

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"保存或删除数据" message:@"删除数据将不可恢复" preferredStyle:UIAlertControllerStyleActionSheet];UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"删除" style:UIAlertActionStyleDestructive handler:nil];UIAlertAction *archiveAction = [UIAlertAction actionWithTitle:@"保存" style:UIAlertActionStyleDefault handler:nil];[alertController addAction:cancelAction];[alertController addAction:deleteAction];[alertController addAction:archiveAction];[self presentViewController:alertController animated:YES completion:nil];

效果展示

这里写图片描述
- 不能在上拉菜单中添加文本框,如果您强行作死添加了文本框,那么就会荣幸地得到一个运行时异常:Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Text fields can only be added to an alert controller of style UIAlertControllerStyleAlert
- 如果上拉菜单中有“取消”按钮的话,那么它永远都会出现在菜单的底部,不管添加的次序是如何(就是这么任性)。其他的按钮将会按照添加的次序从上往下依次显示。《iOS 用户界面指南》要求所有的“毁坏”样式按钮都必须排名第一


iPad或其他常规宽度的设备上拉菜单

1 0
原创粉丝点击