iOS 关于UIAlertController、UIAlertView弹窗问题
来源:互联网 发布:淘宝耐克鞋正品 编辑:程序博客网 时间:2024/06/05 10:28
关于UIAlertController弹窗问题
目标:同时弹出2个以上的弹窗
问题:在弹出一个alertController的时候,第二个alertController是无法弹出的
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"弹窗1" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]; UIAlertAction *skipAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]; [alertController addAction:cancelAction]; [alertController addAction:skipAction]; [self presentViewController:alertController animated:YES completion:nil]; UIAlertController *alertController2 = [UIAlertController alertControllerWithTitle:@"提示" message:@"弹窗2" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]; UIAlertAction *skipAction2 = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]; [alertController2 addAction:cancelAction2]; [alertController2 addAction:skipAction2]; [self presentViewController:alertController2 animated:YES completion:nil];
报错:
xcode给出的理由是:试图呈现已经呈现在self上的alert2
原因分析:
一个视图控制器仅能使用presentViewController模态方法弹出一个控制器
如果想在模态方法弹出第二个视图控制器,可以使用已弹出的alert1来弹出
扩展
使用present,弹出普通的控制器
UIViewController *ctrl1 = [UIViewController new];ctrl1.view.backgroundColor = [UIColor redColor];[self presentViewController:ctrl1 animated:YES completion:nil];UIViewController *ctrl2 = [UIViewController new];ctrl2.view.backgroundColor = [UIColor yellowColor];[self presentViewController:ctrl2 animated:YES completion:nil];NSLog(@"self->%p",self);NSLog(@"111->%p",ctrl1);NSLog(@"222->%p",ctrl2);
结果:系统依旧不能present弹出两个视图,想弹出第二个视图的话,需要将self换成ctrl1;由于UIAlertController是继承自UIViewController的,UIViewController既然不能present弹出两个视图控制器,UIAlertController自然也不行
view is not in the window hierarchy!:视图不在窗口层次结构中
关于UIAlertView弹窗问题
目标:弹出两个提示窗体
UIAlertView *alertView1 = [[UIAlertView alloc] initWithTitle:@"提示" message:@"弹窗1" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];UIAlertView *alertView2 = [[UIAlertView alloc] initWithTitle:@"提示" message:@"弹窗2" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];[alertView1 show];[alertView2 show];
测试结果:是可以弹出两个视图的,会展现最新弹窗,点击消失后,继续弹出之前的弹窗
似乎使用UIAlertView就可以满足弹出两个窗体的需求,但是新的问题随之而来
新问题的产生
在弹出UIAlertView窗体时,如果接下来使用到了[UIApplication sharedApplication].keyWindow.rootViewController来获取控制器等相关操作时,会出现闪退问题
原因:使用UIAlertView的show时,系统使用了一个新的Window来展现UIAlertView,所以当show弹窗时,keyWindow已经被替换
验证:我们来输出keyWindow的内存地址
// 弹窗之前window的内存地址UIWindow *delegateWindow = [UIApplication sharedApplication].delegate.window;UIWindow *keyWindow_pre = [UIApplication sharedApplication].keyWindow;NSLog(@"delegateWindow->%p",delegateWindow);NSLog(@"keyWindow_pre->%p",keyWindow_pre);UIAlertView *alertView1 = [[UIAlertView alloc] initWithTitle:@"提示" message:@"弹窗1" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];UIAlertView *alertView2 = [[UIAlertView alloc] initWithTitle:@"提示" message:@"弹窗2" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];[alertView1 show];[alertView2 show];// 弹窗之后window的内存地址UIWindow *delegateWindow_now = [UIApplication sharedApplication].delegate.window;UIWindow *keyWindow_now = [UIApplication sharedApplication].keyWindow;NSLog(@"delegateWindow_now->%p",delegateWindow_now);NSLog(@"keyWindow_now->%p",keyWindow_now);
结果:
上图可知:
1、在UIAlertView没有使用show之前,delegate.window和keyWindow内存地址是一致的,表示当前的keyWindow就是我们应用的window,一般情况下,两者是同一个
2、在UIAlertView使用show之后,keyWindow发生了变化,已经被系统替换为新的window,这个新的window用来展示UIAlertView;但是此时delegate.window还是原来的那个
结论:
虽然UIAlertView可以解决同时弹出两个弹窗的问题,但是UIAlertView的实现机制会改变keyWindow
如果使用keyWindow的获取应用控制器的时候,最好将keyWindow改成delegate.window,因为keyWindow是会变动的
扩展:验证UIAlertController的keyWindow
验证:将弹窗换成UIAlertController,其他不变
// 弹窗之前window的内存地址UIWindow *delegateWindow = [UIApplication sharedApplication].delegate.window;UIWindow *keyWindow_pre = [UIApplication sharedApplication].keyWindow;NSLog(@"delegateWindow->%p",delegateWindow);NSLog(@"keyWindow_pre->%p",keyWindow_pre);UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"弹窗1" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }];UIAlertAction *skipAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }];[alertController addAction:cancelAction];[alertController addAction:skipAction];[self presentViewController:alertController animated:YES completion:nil];UIAlertController *alertController2 = [UIAlertController alertControllerWithTitle:@"提示" message:@"弹窗2" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction *cancelAction2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }];UIAlertAction *skipAction2 = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }];[alertController2 addAction:cancelAction2];[alertController2 addAction:skipAction2];[self presentViewController:alertController2 animated:YES completion:nil];// 弹窗之后window的内存地址UIWindow *delegateWindow_now = [UIApplication sharedApplication].delegate.window;UIWindow *keyWindow_now = [UIApplication sharedApplication].keyWindow;NSLog(@"delegateWindow_now->%p",delegateWindow_now);NSLog(@"keyWindow_now->%p",keyWindow_now);
结果:
结论:
1、使用UIAlertController并不会改变keyWindow
2、不能弹出两个控制器
综上所述:
1、弹窗两个以上的时候,使用UIAlertView
2、使用keyWindow的地方,最好改为delegate.window,这两者还是有些不同的
3、模态方式跳转视图时,self只能展现一个控制器,若是需要展现第二个,需要当前已经展现的控制器继续模态方式跳转
- iOS 关于UIAlertController、UIAlertView弹窗问题
- iOS 实现类似UIAlertView 和UIAlertController弹窗动画效果
- (iOS开发)关于IOS9以后UIAlertView被UIAlerTController取代的有关问题
- IOS UIAlertView和UIAlertController学习记录
- IOS-UIAlertController(UIAlertView和UIActionSheet二合一)
- iOS--UIAlertView与UIAlertController和UIAlertAction
- iOS UIAlertController代替代替UIAlertView与UIActionSheet
- iOS UIAlertController弹窗效果
- UIAlertController + UIAlertView + UIActionSheet 弹框显示工具
- iOS UIAlertController弹框(OS9.0 后替代UIAlertView弹框和UIActionSheet下弹框)
- 关于ios 中 UIAlertView
- 【学习ios之路:UI系列】UIAlertView. UIActionSheet 和 UIAlertController
- IOS基础UI之(五)UIAlertView、UIActionSheet和UIAlertController详解
- iOS 8 引入的 UIActionSheet 和 UIAlertView 的替代品 - UIAlertController
- 在iOS 9中不在使用UIAlertView使用UIAlertController
- iOS 弹窗UIAlertView、UIActionSheet、UIAlertController简述 —— HERO博客
- IOS开发中UIAlertView与UIAlertController的用法
- iOS 更加优雅便捷的UIAlertView/UIAlertController封装使用
- shell编程报错:“syntax error near unexpected token `”
- python之scikit-learn的应用
- 秘密信息
- 联网判断
- 数组的操作方法
- iOS 关于UIAlertController、UIAlertView弹窗问题
- Java 时间相关 获取某月的某一天
- siege进行压力测试
- bzoj 4552: [Tjoi2016&Heoi2016]排序
- 安卓视频直播
- Rex 密钥认证
- 简单鞍点
- 上周三代码
- maven项目jar包不自动下载