IAlertController 同时替代了 UIAlertView 和 UIActionSheet,从系统层级上统一了 alert 的概念 —— 即以 modal 方式或 popover 方式展示。

UIAlertController 是 UIViewController 的子类,而非其先前的方式。因此新的 alert 可以由 view controller 展示相关的配置中获益很多。

UIAlertController 不管是要用 alert 还是 action sheet 方式展示,都要以 title 和 message 参数来初始化。Alert 会在当前显示的 view controller 中心以模态形式出现,action sheet 则会在底部滑出。Alert 可以同时有按钮和输入框,action sheet 仅支持按钮。

新的方式并没有把所有的 alert 按钮配置都放在初始化函数中,而是引入了一个新类 UIAlertAction 的对象,在初始化之后可以进行配置。这种形式的 API 重构让对按钮数量、类型、顺序方便有了更大的控制。同时也弃用了 UIAlertView 和 UIActionSheet 使用的delegate 这种方式,而是采用更简便的完成时回调。

新旧 Alert 方式对比

标准的 Alert 样式

旧方法:UIAlertView

1
2
3
let alertView = UIAlertView(title: "Default Style", message: "A standard alert.", delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "OK")
alertView.alertViewStyle = .Default
alertView.show()
1
2
3
4
5
6
// MARK: UIAlertViewDelegate
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
    switch buttonIndex {
        // ...
    }
}

新方法:UIAlertController

1
2
3
4
5
6
7
8
9
10
11
12
let alertController = UIAlertController(title: "Default Style", message: "A standard alert.", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
    // ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
    // ...
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
    // ...
}

标准的 Action Sheet 样式

UIActionSheet

1
2
3
let actionSheet = UIActionSheet(title: "Takes the appearance of the bottom bar if specified; otherwise, same as UIActionSheetStyleDefault.", delegate: self, cancelButtonTitle: "Cancel", destructiveButtonTitle: "Destroy", otherButtonTitles: "OK")
actionSheet.actionSheetStyle = .Default
actionSheet.showInView(self.view)
1
2
3
4
5
6
// MARK: UIActionSheetDelegate
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
    switch buttonIndex {
        ...
    }
}

UIAlertController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let alertController = UIAlertController(title: nil, message: "Takes the appearance of the bottom bar if specified; otherwise, same as UIActionSheetStyleDefault.", preferredStyle: .ActionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
    // ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
    // ...
}
alertController.addAction(OKAction)
let destroyAction = UIAlertAction(title: "Destroy", style: .Destructive) { (action) in
    println(action)
}
alertController.addAction(destroyAction)
self.presentViewController(alertController, animated: true) {
    // ...
}

新功能

UIAlertController 并不只是对已有的 API 做了清理,而是进行了标准化归纳。以前,预设的样式闲置有很多(swizzling 虽然可以提供更多的功能但还是有很大风险)。UIAlertController 让以前看起来很神奇的事情变为了可能。

UIAlertController is not just a cleanup of pre-existing APIs, it's a generalization of them. Previously, one was constrained to whatever presets were provided (swizzling in additional functionality at their own risk). With UIAlertController, it's possible to do a lot more out-of-the-box:

带有警示按钮的 Alert

这种行为已经被 UIAlertActionStyle 所涵盖,共有三种类型:

.Default: 对按钮应用标准样式。

.Cancel: 对按钮应用取消样式,代表取消操作不做任何改变。

.Destructive: 对按钮应用警示性的样式,提示用户这样做可能会改变或删除某些数据。

所以想要对模态的 alert 加一个警示性的按钮,只需要加上 .Destructive 风格的 UIAlertAction 属性:

1
2
3
4
5
6
7
8
9
10
11
12
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
    println(action)
}
alertController.addAction(cancelAction)
let destroyAction = UIAlertAction(title: "Destroy", style: .Destructive) { (action) in
    println(action)
}
alertController.addAction(destroyAction)
self.presentViewController(alertController, animated: true) {
    // ...
}

大于 2 个按钮的 Alert

有 1 个或者 2 个操作的时候,按钮会水平排布。更多按钮的情况,就会像 action sheet 那样展示:

1
2
3
4
5
6
7
8
let oneAction = UIAlertAction(title: "One", style: .Default) { (_) in }
let twoAction = UIAlertAction(title: "Two", style: .Default) { (_) in }
let threeAction = UIAlertAction(title: "Three", style: .Default) { (_) in }
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (_) in }
alertController.addAction(oneAction)
alertController.addAction(twoAction)
alertController.addAction(threeAction)
alertController.addAction(cancelAction)

创建登录表单

iOS 5 就为 UIAlertView 加入了 alertViewStyle 属性,将原本私有的 API 暴露出来给开发者使用 —— 像某些系统内建应用一样允许在 alert 中显示登录和密码框。

在 iOS 8 中,UIAlertController 则加入了 addTextFieldWithConfigurationHandler 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let loginAction = UIAlertAction(title: "Login", style: .Default) { (_) in
    let loginTextField = alertController.textFields![0] as UITextField
    let passwordTextField = alertController.textFields![1] as UITextField
    login(loginTextField.text, passwordTextField.text)
}
loginAction.enabled = false
let forgotPasswordAction = UIAlertAction(title: "Forgot Password", style: .Destructive) { (_) in }
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (_) in }
alertController.addTextFieldWithConfigurationHandler { (textField) in
    textField.placeholder = "Login"
    NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, object: textField, queue: NSOperationQueue.mainQueue()) { (notification) in
        loginAction.enabled = textField.text != ""
    }
}
alertController.addTextFieldWithConfigurationHandler { (textField) in
    textField.placeholder = "Password"
    textField.secureTextEntry = true
}
alertController.addAction(loginAction)
alertController.addAction(forgotPasswordAction)
alertController.addAction(cancelAction)

创建注册表单

UIAlertController 想得比以前更周到一些,它提供了展示无限个输入框的权限,并且每一个输入框都可以根据需求进行自定义。这让仅在一个模态的 alert 中实现完善的注册功能成为可能:

1
2
3
4
5
6
7
8
9
10
11
12
alertController.addTextFieldWithConfigurationHandler { (textField) in
    textField.placeholder = "Email"
    textField.keyboardType = .EmailAddress
}
alertController.addTextFieldWithConfigurationHandler { (textField) in
    textField.placeholder = "Password"
    textField.secureTextEntry = true
}
alertController.addTextFieldWithConfigurationHandler { (textField) in
    textField.placeholder = "Password Confirmation"
    textField.secureTextEntry = true
}

虽然有了这些,但必须要说明的是,不用矫枉过正。不能因为你可以这样做,就代表你应该这样做。忘了这玩意吧,提供一个 view controller 来做注册功能吧,因为你本就应该这样做!

注意

如果试图向 alert controller 添加带有 .ActionSheet 属性的输入框,将会抛出异常:

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

同样的,向 alert 或 action sheet 添加一个以上的 .Cancel 按钮将会抛出异常:

1
Terminating app due to uncaught exception NSInternalInconsistencyException, reason: '

UIAlertController 的使用的更多相关文章

  1. UIAlertController

    楼主在整理项目的警告,于是乎你懂的. 然后自己整理了一下以后方便自己忘了之后能及时找到它 关于UIAlertController .h文件的解析 /** 关于UIAlertController的解析 ...

  2. iOS UIAlertController跟AlertView用法一样 && otherButtonTitles:(nullable NSString *)otherButtonTitles, ... 写法

    今天写弹出框UIAlertController,用alertView习惯了,所以封装了一下,跟alertView用法一样,不说了,直接上代码: 先来了解一下otherButtonTitles:(nul ...

  3. UIAlertController使用

    // 将UIAlertController模态出来 相当于UIAlertView show 的方法// 初始化一个一个UIAlertController    // 参数preferredStyle: ...

  4. IOS UIAlertController 使用方法

    在很多种语言中,alert都表示弹窗操作,弹窗功能非常有用,不仅可以用于正式的app功能中,也可以在调试中使用.在OC中,UIAlertController类用来控制弹窗操作.在IOS 8.0之前, ...

  5. UI控件(UIAlertController)

    @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIButton *_button = [UIBut ...

  6. UIAlertController 部分用法及属性

    //创建UIAlertController:初始化UIAlertController 需要使用alertControllerWithTitle UIAlertController *alertCont ...

  7. iOS--UIAlertView与UIAlertController和UIAlertAction之间的事儿

      iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.全新的UIPresentationController在实现视图控制器间的过渡动画效果和自适应设备 ...

  8. 开始使用 UIAlertController 吧

    UIAlertView 与 UIActionSheet UIAlertView 样式 实现 - (void)showAlertView { self.alertView = [[UIAlertView ...

  9. UI第十四节——UIAlertController

    - (void)viewDidLoad {    [super viewDidLoad];        UIButton *alertBtn = [UIButton buttonWithType:U ...

  10. iOS 8.0后使用UIAlertController

    iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.全新的UIPresentationController在实现视图控制器间的过渡动画效果和自适应设备尺寸 ...

随机推荐

  1. HDU5709 : Claris Loves Painting

    对于每个点维护两棵线段树$T1[x],T2[x]$: $T1[x]$维护$x$子树内,深度在$[l,r]$内的点数,同种颜色有多个的话,保留深度最小的那个. $T2[x]$维护$x$子树内每种颜色的最 ...

  2. InterBase数据库迁移到MySQL(数据导入)

    在这个脚本中我使用的是Python的ORM框架SQLAlchemy来连接远程的MySQL数据库的,在写这个脚本的时候为了方便参数的输入,我就给之前和这个脚本添加了一个新的功能,就是在调用这个脚本的时候 ...

  3. BZOJ4551: [Tjoi2016&Heoi2016]树

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标 ...

  4. iOS 网络框架编写总结

    一,常用 1> 不错的处理接收到的网络图片数据的方法 id img= ISNSNULL(pic)?nil:[pic valueForKey:@"img"]; NSString ...

  5. This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release.

    一,经历 <1> 使用SDWebImage下载 成功图片后,将图片设置给 self.imageView.image,提示如题所示的错误提示. <2>第一反应就是慢慢注释掉代码进 ...

  6. jQuery 基本过滤选择器注意点

    $(".add_shuxing_ul > li:first")  选择class为add_shuxing_ul 的子级li元素的第一个li $(".add_shux ...

  7. HDU-1466 计算直线的交点数 经典dp

    1.HDU-1466   计算直线的交点数 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=1466 3.总结:不会推这个,看了题解.. 状态转移: m条 ...

  8. Oracle 游标使用全解(转)

    -- 声明游标:CURSOR cursor_name IS select_statement --For 循环游标 --(1)定义游标 --(2)定义游标变量 --(3)使用for循环来使用这个游标 ...

  9. JSP自定义标签开发入门

    一般情况下开发jsp自定义标签需要引用以下两个包 import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; 首先我们需要大致了解开发 ...

  10. 用脚本来简化iOS美术同学的工作

    用脚本来简化iOS美术同学的工作 问题 我们知道,在 iOS 开发中,为了使我们的 app 能够同时支持 iPhone 的 Retina 屏幕和普通屏幕,美术同学需要对 UI 设计稿中的每个元素进行 ...