问题描述

如果当前页面有UITextField时使用UIAlertView,在pop或者push时,在新的页面键盘会弹出一下,再收回。这个问题困扰了我很久,一开始没意识到这是iOS8系统以后导致的问题,因为当时接手这个项目的时候刚刚发布iOS8没多久,我的测试机还是iOS7,没有这个问题,只是在同事iOS8的手机上能见到,当时以为只是偶发现象觉得不严重也就没去处理。现在应用做扩展升级,发现这个问题几乎每个机子上都会发生,大部分的机子现在都是iOS8+和iOS9+。下午没事儿就想把这个由来已久的问题解决一下。网上搜到了导致这个现象的原因:在ios8以后,苹果提倡使用UIAlertController而非UIAlertView,键盘收回动作需要0.25s的时间,而UIAlertView弹出是阻碍了键盘的收回动作。
由于目前应用还是要支持iOS7+所以不能全部换成UIAlertController,只好用一下折中的办法。

解决

1.网上大部分的解决办法都是说判断系统,iOS8+的用UIAlertController,低于iOS8的用UIAlertView。而且大部分人提倡的都是这种办法,可是我觉得代码太长了,由于我的系统中一个页面的好几个地方都有这种提示,那么光写提示就得写上百行了😓。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (SYSTEM_VERSION >= 8.0) {
UIAlertController *alc = [UIAlertController alertControllerWithTitle:@"提示" message:@"是否要保存" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sure = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self commitData];
}];
[alc addAction:sure];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self.navigationController popViewControllerAnimated:YES];
}];
[alc addAction:cancel];
[self presentViewController:alc animated:YES completion:nil];
}else{
UIAlertView*al=[[UIAlertView alloc]initWithTitle:@"提示" message:@"是否要保存" delegate:self cancelButtonTitle:@"否" otherButtonTitles:@"是", nil];
[al show];
}

2.既然是因为键盘收回动画时间导致的,那么在alert的时候延迟一下,给键盘足够的动画时间就好了,这样代码量还少点。

1
2
3
4
5
6
UIAlertView *alertView =[[UIAlertView alloc]initWithTitle:@"提示" message:@"保存成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
double delayInSeconds = 0.33f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[alertView show];
});

参考链接:

关于使用UIAlertView之后pop或者push时键盘闪退问题解决方法
知乎:pop 一个viewController时候会有键盘闪现出来又消失, 请教原因和解决方法?参见藏其龙的回答。