1.UIAlertController
- 在iOS8 中添加了新的类UIAlertController和UIAlertAction来取代曾经的UIAlertView和UIActionSheet,感觉警告窗口的结构更容易理解了,使用起来也更简便。
- 在iOS8中,UIAlertController控件使用两种样式代替UIAlertView和UIActionSheet
- 意想不到的事情是UIAlertController的父类是UIViewController,所以要想显示出来不再是之前的show方法,而是使用推出模态视图的方式推出
- 在UIAlertController中,并没有按钮的添加,有的是Title和Message这样的信息显示,而按钮,则是放在UIAlertAction类中了
- 如果我们想要添加一个按钮,通过创建UIAlertAction对象进行添加,按钮的事件也不再使用代理方法,而是通过Block的方式,我们可以添加多个按钮
- 除此之外,UIAlertController也可以添加UITextField,UITextField的设置放在了Block内部,我们可以通过数组alertController.textFields来获取添加的输入框中的值,同样,输入框我们可以添加多个
- 注意:输入框的添加只能在alertView样式下添加,如果是在actionSheet方式下添加,会造成运行时错误,所以在添加输入框前最好添加判断
- 为了弹出提示信息,大致需要完成以下几个步骤:1) 创建一个UIAlertController,设置它的标题、内容以及式样。2) 定义UIAlertAction对象,并且把它加到AlertController中。3)通过调用presentViewController方法弹出内容。
- (void)importPhoneNum{
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"提示" message:@"张阳阳" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertVC animated:YES completion:nil];
[alertVC addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = @"请输入手机号";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeText:) name:UITextFieldTextDidChangeNotification object:textField];
}];
UIAlertAction *cancelActin = [UIAlertAction actionWithTitle:@"取消" style:0 handler:^(UIAlertAction *action) {
}];
UIAlertAction *sureActin = [UIAlertAction actionWithTitle:@"确定" style:0 handler:^(UIAlertAction *action) {
UITextField *textField = alertVC.textFields[0];
NSLog(@"%@",textField.text);
}];
[alertVC addAction:cancelActin];
[alertVC addAction:sureActin];
sureActin.enabled = NO;
}
- (void)changeText:(NSNotification *)notification{
UIAlertController *alertVC = (UIAlertController *)self.presentedViewController;
UITextField *textFielf = alertVC.textFields[0];
UIAlertAction *action = alertVC.actions[1];
action.enabled = textFielf.text.length == 11;
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
2.常见的传值方式
- 常用于处理确定执行顺序的传值:属性传值(这里把block拆出去了)(KVO传值到同一页面触发的那个方法里面)
属性传值,这就没啥好说的了,比如vc2.orderList = vc1.orderList,在MRC下要注意retain,还是copy,ARC下就只有strong了。常见的错误就是执行循序了,经常有人在vc2重写init方法,然后直接在init方法里使用orderList,然后在vc1里写,vc2 = [[vc2 alloc]init]; vc2.orderList = vc1.orderList; 结果发现怎么用这个值都是空的。init方法里,值都还没传过来,怎么用? - 常用于处理不确定执行顺序的传值:代理传值,block传值
代理传值,很多人喜欢说什么委托者,代理者,我一般是说,A创建B,B在某一个时刻把值传给A。原理就是B有一个属性是A,然后让A去干一些事。具体是什么事,由他们俩签的协议protocol决定。 这里需要注意的是,B在用A这个属性调方法的时候,要先判断A是否指向nil,并且A是否能执行这些方法。还有一个需要主意的是delegate的属性,一般为assign,防止循环应用。这里就不细说了,网上讲委托代理的文章一大堆。
block传值,block传值说起来也算是属性传值的一种,只是这个属性传值,传的值比较特殊,类似于传递函数指针,然后我们在特定情况下,比如网络请求收到响应,把这个函数指针拿出来调用函数。这样就达到传递代码片段的目的。block传值有两个常见的坑,一个是没有判断block这个属性是否指向nil直接拿过来调用,如果这个时候block为nil,会直接crash。第二个坑是循环引用,两个对象互相持有,谁也释放不了谁,所以一般传值进block的时候先转weak,等到block里的时候再转strong。 - 都适用的:单例传值,通知传值
单例传值,单例传值的话,有点类似全局变量,单例本质就是程序运行的时候,这块内存空间一直不释放,有什么值就在这块内存空间读写。
通知传值,一般是用在,我不确定什么时候,有谁需要去执行。比如我有3个页面都是显示未付款,这个时候网络请求响应付款成功,我需要三个页面都变成已付款。那就在需要改变状态的3个页面注册观察者,让他们监听某一事件,然后在网络请求那边post消息出去,这3个观察者都是接到。通知传值有个坑就是,观察者用完要销毁。还有就是相对于代理而言,会比较消耗系统资源。