在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有两个枚举常量:
[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];
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个字符才能激活“登陆”按钮。
[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;
}];
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 用户界面指南》要求所有的“毁坏”样式按钮都必须排名第一