博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从UIAlertView、UIActionSheet到UIAlertController
阅读量:7119 次
发布时间:2019-06-28

本文共 9311 字,大约阅读时间需要 31 分钟。

文章更新:

3月9日:推荐一个开源框架GJAlertController

许多时候,我们需要在应用中弹出提示框,给用户提示信息,然后让用户选择执行哪种操作。有两种形式,一种是弹出提示框,一种是弹出提示菜单。

  • 提示框:进入Apple Music,在登录时,会弹出提示输入AppleID账户和密码的提示框。

    image

  • 提示菜单:在Apple Music中,选择将一首歌曲加入到播放列表时,弹出如下菜单。

    image

UIAlertView

在iOS 9.0中,UIAlertView被弃用。当然,UIAlertViewDelegate同样被弃用。取而代之的是,使用UIAlertController,初始化时,将preferredStyle设为UIAlertControllerStyleAlert

初始化UIAlertView

使用

- (instancetype)initWithTitle:(NSString *)title                      message:(NSString *)message                     delegate:(id)delegate            cancelButtonTitle:(NSString *)cancelButtonTitle            otherButtonTitles:(NSString *)otherButtonTitles,, ...

初始化UIAlertView的实例。

注意:参数otherButtonTitles可以有多个NSString,有分号隔开,以nil结尾即可。

这里直接上代码,看一下出现的效果。

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title"                                                        message:@"message"                                                       delegate:self                                              cancelButtonTitle:@"Cancel"                                              otherButtonTitles:@"Other1", nil];

效果如下:

image

如果otherButtonTitles参数有多个NSString时,效果如下:

image

我们也可以使用

- (NSInteger)addButtonWithTitle:(NSString *)title

来添加UIAlertView所显示的按钮。

@property(nonatomic, copy) NSString *title@property(nonatomic, copy) NSString *message

可以设置这两个属性改变titlemessage

不建议添加太多的按钮,否则会降低用户体验。

代理方法

在初始化方法中有参数delegate,所以,如果要响应按钮点击事件,需要当前ViewController遵循UIAlertViewdelegate

如果初始化方法中的otherButtonTitles不为nil,那么必须要实现

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

buttonIndex从0开始计算。这个方法调用之后,UIAlertView会自动消失。

- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView

这个方法可以用与输入框的UIAlertView。当没有用户没有输入完成时,令这个方法返回NO,使用户无法点击第一个添加的按钮。

//alertView即将呈现给用户时调用- (void)willPresentAlertView:(UIAlertView *)alertView//alertView已经呈现给用户时调用- (void)didPresentAlertView:(UIAlertView *)alertView//用户点击某个按钮后,alertView即将消失时调用- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex//用户点击某个按钮后,alertView已经消失时调用- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex

在后两个代理方法中,buttonIndex的值从0开始计算。在我初始化的alertView中,cancel对应索引0other1对应索引1other2对应索引2

alertView的样式

我们可以通过alertViewStyle属性改变alertView的样式。

  • UIAlertViewStyleDefault。弹出一个标准的alertView;

  • UIAlertViewStyleSecureTextInput。弹出的alertView带有一个密码输入框;

  • UIAlertViewStylePlainTextInput。弹出的alertView带有一个普通的文本输入框;

  • UIAlertViewStyleLoginAndPasswordInput。弹出的alertView有两个输入框,可以分别输入账号密码。

几个属性和方法

//获取特定按钮的索引@property(nonatomic) NSInteger cancelButtonIndex@property(nonatomic, readonly) NSInteger firstOtherButtonIndex//返回对应索引的UITextField- (UITextField *)textFieldAtIndex:(NSInteger)textFieldIndex//UIAlertViewStyleDefault,没有text field。//UIAlertViewStyleSecureTextInput,text field对应索引0。//UIAlertViewStyleDefault,text field对应索引0。//UIAlertViewStyleDefault,login field对应索引0,password field对应索引1。//如果参数`textFieldIndex`超出索引范围,则会抛出`NSRangeException`异常。 //返回指定索引的按钮的值- (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex//弹出alertView- (void)show

UIActionSheet

UIActionSheet和UIActionSheetDelegate在iOS 8.3中被弃用。取代它的是preferredStyle被设为UIAlertControllerStyleActionSheetUIAlertController

在我使用App的过程中,两种情况下使用UIActionSheet。

  • 当用户删除东西的时候,给出提示;

  • 在上传头像时,选择用相机拍照还是相册照片。

初始化UIActionSheet

- (instancetype)initWithTitle:(NSString *)title                     delegate:(id
)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...

UIActionSheet的初始话方法和UIAlertView的初始化方法类似。

同样地,给出一行初始化代码,看看效果。

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil                                                             delegate:self                                                    cancelButtonTitle:@"cancel"                                               destructiveButtonTitle:@"destructive"                                                    otherButtonTitles:@"使用相机拍照", @"选择相册照片", nil];

image

destructiveButtonTitleotherButtonTitles根据情况传值,二选一,否则就会像上图所显示的那样,看起来很丑!

代理方法

UIActionSheet的代理方法定义在协议UIActionSheetDelegate中。它的代理方法和UIAlertViewDelegate中定义的方法是极其相似的。

//添加的按钮被点击调用- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex//actionSheet即将出现时调用- (void)willPresentActionSheet:(UIActionSheet *)actionSheet//actionSheet已经出现时调用- (void)didPresentActionSheet:(UIActionSheet *)actionSheet//actionSheet即将消失时调用- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex//actionSheet已经消失时调用- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex

对于actionSheet中按钮的索引,是按照从0开始,从上到下依次+1。依然以我初始化的actionSheet为例,destructive的索引是0,使用相机拍照的索引是1,选择相册照片的索引是2,cancel的索引是3。

一些属性和方法

//获取特定的按钮的索引@property(nonatomic) NSInteger cancelButtonIndex@property(nonatomic) NSInteger destructiveButtonIndex@property(nonatomic, readonly) NSInteger firstOtherButtonIndex//返回指定索引的按钮的值- (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex//显示actionSheet- (void)showInView:(UIView*)view

总结UIAlertView和UIActionSheet

这两个的类的属性、方法、代理都极其相似。

需要注意的是,当它们都有多个按钮时,计算按钮索引的方法是不同的。

  • UIAlertView的取消按钮的索引永远是0,其他的依次+1。

  • UIActionSheet的索引是所有的按钮从上到下,从0开始,一次+1。

- (void)alertViewCancel:(UIAlertView *)alertView- (void)actionSheetCancel:(UIActionSheet *)actionSheet

这两个代理方法在什么情况下会调用,我没有搞清楚!

UIAlertController

到了iOS 9.0之后,UIAlertView和UIActionSheet都被弃用了,取而代之的就是UIAlertController。实际上,UIAlertController在iOS 8.0以后就可以使用了。

UIAlertController是继承自UIController的,所以,使用presentViewController:animated:completaion:方法来显示UIAlertController。

首先,我把上面给出的UIAlertView和UIActionSheet的初始化,使用UIAlertController来实现。

//实现和UIAlertView相同的效果UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancelhandler:^(UIAlertAction * _Nonnull action) {    nil;}];UIAlertAction* firstOtherAction = [UIAlertAction actionWithTitle:@"Other1" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {    NSLog(@"other1 clicked!");}];UIAlertAction* secondOtherAction = [UIAlertAction actionWithTitle:@"Other2" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {    NSLog(@"other2 clicked!");}];[alert addAction:cancelAction];[alert addAction:firstOtherAction];[alert addAction:secondOtherAction];[self presentViewController:alert animated:YES completion:^{    nil;}];

image

//实现和UIActionSheet相同的效果UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleActionSheet];UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {    nil;}];UIAlertAction* destructiveAction = [UIAlertAction actionWithTitle:@"destructive" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {    NSLog(@"destructive clicked");}];UIAlertAction* firstAction = [UIAlertAction actionWithTitle:@"使用相机拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {    NSLog(@"使用相机拍照");}];UIAlertAction* secondAction = [UIAlertAction actionWithTitle:@"使用相册照片" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {    NSLog(@"使用相册照片");    }];[alert addAction:cancelAction];[alert addAction:firstAction];[alert addAction:destructiveAction];[alert addAction:secondAction];[self presentViewController:alert animated:YES completion:^{    nil;}];

image

比较上面的两段代码,可以发现一些共同点:

  • UIAlertController使用alertControllerWithTitle:message:preferredStyle:实例化一个对象。

  • 都用到了UIAlertAction类,和addAction:方法。

  • 都使用了presentViewController:animated:completion:方法显示。

其实,上述总结的共同点就是UIAlertController对象被实例化,然后添加每个按钮以及按钮所需要响应的事件的一个过程。

初始化方法

+ (instancetype)alertControllerWithTitle:(NSString *)title                                 message:(NSString *)message                          preferredStyle:(UIAlertControllerStyle)preferredStyle

这是UIAlertController的类方法,其中的preferredStyle参数的值,决定了它显示的样式。如果是UIAlertControllerStyleAlert,那么会显示一个alertView。如果是UIAlertControllerActionSheet,那么会显示一个actionSheet

UIAlertAction

这个类的作用就是给UIAlertController添加按钮,以及按钮所响应的事件。

+ (instancetype)actionWithTitle:(NSString *)title                          style:(UIAlertActionStyle)style                        handler:(void (^)(UIAlertAction *action))handler

在这个初始化方法中,style参数指定按钮显示的样式,而handler这个Block里放按钮点击后需要执行的操作。

style这个参数可以选择3个值:

  • UIAlertActionStyleDefault。显示常规的按钮样式。

  • UIAlertActionStyleCancel。显示取消按钮的样式,是加粗的。

  • UIAlertActionStyleDestructive。显示红色的文字。一般情况下,表示这个按钮点击后可能会改变或者删除数据。

在实例化UIAlertAction的对象之后,需要使用addAction:方法,将他们添加到UIAlertController上。除了取消按钮外,添加的顺序决定了按钮在UIAlertController上显示的顺序。

只能在UIAlertControllerStyleAlert下使用的一些特殊的设置

preferredAction

这个属性值默认为nil。

赋给这个属性的alertAction必须已经添加到UIAlertController中,否则运行后会crash。设置之后,对应的按钮的文字会被加粗显示。_所有的按钮的文字只有一个是加粗显示的。_

文本输入框

- (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler

这个方法可以为alertController添加一个文本框。这个方法所带的block参数可以用来设置文本框的样式。这个方法可以多次被调用,被一次添加到UIAlertController中。

结语

一般情况下,我们的App需要适配到iOS 7.0。所以,我们依然可以使用UIAlertViewUIActionSheet,并且,它们可以在iOS 9.0以上的设备上运行的。话虽如此,进行适配肯定会为我们规避不可预估的不良后果。

给大家推荐一个在iOS 8上使用UIAlertController的框架 —— 。框架的作者为大家讲解了内部的实现方式,大家可以参考。

转载地址:http://yusel.baihongyu.com/

你可能感兴趣的文章
[开源]快速构建文件下载,支持文件加密,自定义限速
查看>>
Mac系统搭建java开发环境
查看>>
菜鸟对新技术的一点看法
查看>>
2016年2月23日----Javascript全局变量和局部变量
查看>>
iOS开发基础知识-多线程概念深入浅出
查看>>
论PHP框架设计模式及MVC的缺陷
查看>>
立flag(java)
查看>>
7-38 数列求和-加强版(20 分)
查看>>
python----字典
查看>>
开发环境eclipse for Mac 下的常用快捷键汇总(基本参照Win系,将Ctrl换为Command)
查看>>
tree与GridView交互
查看>>
zz 鸡汤穷三代,励志毁一生
查看>>
小学期实践心得(2)
查看>>
c#获取电脑硬件信息参数说明(CPU篇 Win32_Processor)
查看>>
oracle报错注入的一些函数
查看>>
Android下载图片/调用系统相机拍照、显示并保存到本地
查看>>
LeetCode算法题-Detect Capital(Java实现)
查看>>
Java GC 原理
查看>>
strust2 和 hibernate的整合------登录的实现
查看>>
关于BOF改进方法的一些introduction
查看>>