本文记录的是,当在UIViewController的根view.window上添加子视图maskView,且在该子视图maskView上的某一操作会触发UIAlertController的弹出的情况下,如何保证UIAlertController是显示在整个视图的最上方。如不做任何处理,UIAlertController会处在子视图maskView的视图层级之下,如下图所示:

错误显示的UIAlertController
错误显示的UIAlertController

此时,主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
- (IBAction)showPopView:(id)sender {

UIView *maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height)];
maskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];

CGFloat leftMargin = 50;
CGFloat topMargin = 80;
CGRect popViewFrame = CGRectMake(leftMargin, topMargin, SCREEN_SIZE.width - 2 * leftMargin, 200);
UINib *viewNib = [UINib nibWithNibName:@"PopView" bundle:nil];
NSArray *views = [viewNib instantiateWithOwner:self options:nil];
for (id view in views) {
if ([view isKindOfClass:[PopView class]]) {
_popView = view;
}
}
_popView.frame = popViewFrame;
[_popView.showAlertBtn addTarget:self action:@selector(showAlertBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
[maskView addSubview:_popView];

[self.view.window addSubview:maskView];
}

- (void)showAlertBtnPressed:(id)sender {
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"我要在最上面" message:@"谁也别惹我" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:confirmAction];
[self presentViewController:alertController animated:YES completion:nil];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"我要在最上面" message:@"谁也别惹我" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alertView show];
}
}

要想正确显示UIAlertController,需要用到UIWindow的创建及切换。首先创建一个UIWindow对象,如下:

1
2
3
4
5
6
7
8
9
10
11
@property (strong, nonatomic) UIWindow *alertWindow;

- (UIWindow *)alertWindow {
if (!_alertWindow) {
_alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *viewController = [[UIViewController alloc] init];
_alertWindow.rootViewController = viewController;
}

return _alertWindow;
}

然后在presentViewController的时候进行UIWindow的切换,如下所示:

1
2
[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];

最后,在用户进行交互操作让UIAlertController消失的时候将UIWindow切换回系统的window,如下所示:

1
2
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.window makeKeyAndVisible];

整个显示UIAlertController代码改变后如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (void)showAlertBtnPressed:(id)sender {
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"我要在最上面" message:@"谁也别惹我" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.window makeKeyAndVisible];
}];
[alertController addAction:confirmAction];

[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"我要在最上面" message:@"谁也别惹我" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alertView show];
}
}

效果图如下:

正确显示的UIAlertController
正确显示的UIAlertController

另外,在 iOS8.0 以下使用UIAlertView时不会出现任何问题,不用做任何更改.


如果觉得本文对你有帮助,就请用微信打赏我吧^_^