ios 8.3 在显示 alert view 或 alertcontroller 时键盘会自动出现
Keyboard will appeared automatically in ios 8.3 while displaying alertview or alertcontroller
我已经更新了 Xcode 6.3 和 ios8.3 检查我的代码。然后它给了我奇怪的结果。
这是我的演示应用程序的第一个屏幕。这是一个文本字段。当我在打开的文本字段键盘中输入内容时。
输入完成后。我点击了显示警报按钮。我已经显示警报,输出将如下。
点击取消后。
我显示了另一个警报然后奇怪的结果键盘不应该打开但是当点击取消按钮时。显示另一个警报,键盘将自动出现。
这是下一个屏幕输出
代码如下
- (IBAction)MethodShowAlert:(id)sender
{
[tmptxtField resignFirstResponder];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Check Alert textField" message:@"keyboard should not be open" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self showCustomAlertWithTitle:nil];
}
-(void)showCustomAlertWithTitle:(NSString *)title{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Now Check" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alertView show]
}
是的,很奇怪。
但是从 iOS 8 开始,我建议使用 UIAlertController 而不是 UIAlertView。
用这个替换你的代码:
- (IBAction)MethodShowAlert:(id)sender
{
[tmptxtField resignFirstResponder];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"Check Alert textField"
message:@"keyboard should not be open"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self showCustomAlertWithTitle:@"Now Check"];
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
-(void)showCustomAlertWithTitle:(NSString *)title{
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:title
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:YES completion:nil];
}
点击按钮后键盘不会显示。
这是 iOS 8.3 中引入的行为更改。尝试下载 iOS 8.2 模拟器,您会看到旧的行为。
我的分析结果如下:
- 显示警报时,它会保存当前显示的键盘。
- 警报完成关闭动画后,它会恢复之前保存的键盘。
所以在 -[id<UIAlertViewDelegate> alertView:clickedButtonAtIndex:]
中,您处于这些状态之间。那么同时显示两个警报会发生什么:
- 显示警报 1。保存可见键盘。隐藏键盘。
- 用户点击警报。
- 显示警报 2。保存没有键盘。
- Alert1 完成关闭动画。恢复保存的键盘。键盘可见。
- 用户点击警报。
- 警报 2 已关闭。恢复没有键盘。隐藏键盘。
我的建议是使用 UIAlertViewDelegate
方法,该方法在关闭动画完成后调用,然后显示下一个警报。
在我的例子中,我尝试在显示警报之前隐藏键盘,因此它不会将键盘保存在内存中以在自行关闭后再次显示它。
为此你只需要关闭键盘,这将花费默认的动画时间来隐藏,然后你应该显示警报视图然后它不会保存该键盘。
您必须在隐藏键盘和显示警报之间留出大约 0.6 秒的间隔
[YOUR_TEXT resignFirstResponder];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_alertVw = [[UIAlertView alloc] initWithTitle:@"" message:@"message." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[_alertVw show];
});
用下面的方法替换您的警报方法。
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:messege 标题 message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
我还尝试在显示警报之前直接隐藏键盘。
对我有用的是调用 [myTextField endEditing:YES];
而不是 [myTextField resignFirstReponder];
这让键盘保持隐藏状态,即使在再次解除警报后也是如此。
代码如下所示:
[myTextField endEditing:YES];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"myTitle"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"NO"
style:UIAlertActionStyleCancel
handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"YES"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
我已经更新了 Xcode 6.3 和 ios8.3 检查我的代码。然后它给了我奇怪的结果。
这是我的演示应用程序的第一个屏幕。这是一个文本字段。当我在打开的文本字段键盘中输入内容时。
输入完成后。我点击了显示警报按钮。我已经显示警报,输出将如下。
点击取消后。 我显示了另一个警报然后奇怪的结果键盘不应该打开但是当点击取消按钮时。显示另一个警报,键盘将自动出现。
这是下一个屏幕输出
代码如下
- (IBAction)MethodShowAlert:(id)sender
{
[tmptxtField resignFirstResponder];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Check Alert textField" message:@"keyboard should not be open" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self showCustomAlertWithTitle:nil];
}
-(void)showCustomAlertWithTitle:(NSString *)title{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Now Check" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alertView show]
}
是的,很奇怪。
但是从 iOS 8 开始,我建议使用 UIAlertController 而不是 UIAlertView。
用这个替换你的代码:
- (IBAction)MethodShowAlert:(id)sender
{
[tmptxtField resignFirstResponder];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"Check Alert textField"
message:@"keyboard should not be open"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self showCustomAlertWithTitle:@"Now Check"];
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
-(void)showCustomAlertWithTitle:(NSString *)title{
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:title
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:YES completion:nil];
}
点击按钮后键盘不会显示。
这是 iOS 8.3 中引入的行为更改。尝试下载 iOS 8.2 模拟器,您会看到旧的行为。
我的分析结果如下:
- 显示警报时,它会保存当前显示的键盘。
- 警报完成关闭动画后,它会恢复之前保存的键盘。
所以在 -[id<UIAlertViewDelegate> alertView:clickedButtonAtIndex:]
中,您处于这些状态之间。那么同时显示两个警报会发生什么:
- 显示警报 1。保存可见键盘。隐藏键盘。
- 用户点击警报。
- 显示警报 2。保存没有键盘。
- Alert1 完成关闭动画。恢复保存的键盘。键盘可见。
- 用户点击警报。
- 警报 2 已关闭。恢复没有键盘。隐藏键盘。
我的建议是使用 UIAlertViewDelegate
方法,该方法在关闭动画完成后调用,然后显示下一个警报。
在我的例子中,我尝试在显示警报之前隐藏键盘,因此它不会将键盘保存在内存中以在自行关闭后再次显示它。
为此你只需要关闭键盘,这将花费默认的动画时间来隐藏,然后你应该显示警报视图然后它不会保存该键盘。
您必须在隐藏键盘和显示警报之间留出大约 0.6 秒的间隔
[YOUR_TEXT resignFirstResponder];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_alertVw = [[UIAlertView alloc] initWithTitle:@"" message:@"message." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[_alertVw show];
});
用下面的方法替换您的警报方法。
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:messege 标题 message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
我还尝试在显示警报之前直接隐藏键盘。
对我有用的是调用 [myTextField endEditing:YES];
而不是 [myTextField resignFirstReponder];
这让键盘保持隐藏状态,即使在再次解除警报后也是如此。
代码如下所示:
[myTextField endEditing:YES];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"myTitle"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"NO"
style:UIAlertActionStyleCancel
handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"YES"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];