在 iOS 8.3 for iPad 上关闭 UIAlertView 后键盘弹出
Posted
技术标签:
【中文标题】在 iOS 8.3 for iPad 上关闭 UIAlertView 后键盘弹出【英文标题】:Keyboard pops up after UIAlertView is dismissed on iOS 8.3 for iPad 【发布时间】:2015-05-08 17:09:33 【问题描述】:随着最新的 ios 8.3 版本,我们的应用开始出现奇怪的行为。
完成文本字段编辑后,用户可以单击关闭按钮,该按钮会弹出UIAlertView
。当用户在 alertview 中点击 discard 时,alertview 和 current view 将被关闭。但不知何故,在视图消失后键盘会出现,这对用户来说非常烦人。
经过一些调试,似乎在关闭视图之前用户访问的最后一个文本字段显示了键盘。我在很多地方尝试了各种方法来endEditing
用于当前视图(在显示UIAlertView
之前,单击UIAlertView
中的按钮后;我什至将焦点设置到视图的另一个UI 元素)。它没有解决问题。
但对于这个特定问题,我不确定这是一个常见问题还是我们需要解决的问题。在 iOS 8.3 之前一切正常。
我们了解到 UIAlertView
在 iOS 8 中已被弃用。我们开始迁移到 UIAlertController
。但如果有任何解决方法,我们很乐意听到。
这里有一些代码 sn-p。
- (IBAction)closeTapped:(UIButton *)sender
// try to resign first responder
// [self.tfName resignFirstResponder];
// [self.tfPosition resignFirstResponder];
[self.view endEditing:YES];
if(self.orderDetails.isOpen && self.orderItemChanged)
UIAlertView* saveAlert = [[UIAlertView alloc] initWithTitle:@"Unsaved Changes"
message:@"Your changes have not been saved. Discard changes?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Save", @"Discard", nil];
[saveAlert show];
else
[self close];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
switch(buttonIndex)
case 1: // Save
[self save];
break;
case 2: // Discard
[self close];
break;
- (void)close
[self.delegate dismissEditOrderItemVC];
【问题讨论】:
在显示警报视图之前,您是否尝试在文本字段上调用 resignFirstResponder? 是的,我为所有文本字段做了 resignFirstResponder 并为当前视图做了 endEditing。似乎不起作用:( 您可能需要向我们展示代码才能进一步提供帮助。似乎解除警报视图正在触发视图控制器上的一些生命周期调用。 我在原始帖子中添加了一个代码 sn-p。谢谢。 Keyboard loses hiding ability "if I use a UIAlertView" 的可能重复项 【参考方案1】:如果您的部署目标是 iOS 8+,请尝试UIAlertController
。
这是UIAlertView
的快速修复:当您的文本字段或文本视图退出第一响应者时,延迟显示警报视图的调用。
[self performSelector:@selector(showAlertView) withObject:nil afterDelay:0.6];
【讨论】:
为我工作。您选择使用 0.6 延迟的任何原因? @KeithAylwin 我随机拿起号码。您可以根据需要选择其他号码:)【参考方案2】:如果有人对此感到困惑,我希望这会有所帮助:
if (NSClassFromString(@"UIAlertController"))
UIAlertController* alert = ...
else
UIAlertView* alert = ...
【讨论】:
这不是根本检查UIAlertController
是否可用的方式。如果类不存在,您应该使用 if (NSClassFromString(@"UIAlertController"))
而不是返回 nil
。使用上述方法会导致您的应用在 iOS 7.1 或更早版本上崩溃。
当你投反对票时,请至少解释原因。简单地按下并不能帮助查看答案有什么问题,或者至少在编辑后还剩下什么。
我不同意在您编辑后 否决这个答案(这是针对@pkamb,而不是您@puzzler)。我对以前形式的答案投了反对票,但在编辑时我删除了这个投票。如果我已经在队列中进行了审核,我也不确定我是否会接受该编辑。
之前状态的答案似乎是“使用此代码编辑: 等待改用此代码”。我在前面编辑了读者被告知忽略的部分。如果我删除了太多内容,请随时添加到当前答案中,并接受我的道歉。
所以实际上当前形式的答案是正确的。这就是我需要知道的。谢谢两位的解释。【参考方案3】:
您需要更改 ios 8.3 的警报
首先把它放在你的视图中
#define IS_IOS8 [[UIDevice currentDevice].systemVersion floatValue] >= 8.0
然后
if (IS_IOS8)
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Unsaved Changes" message:@"Your changes have not been saved. Discard changes?" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *saveAction = [UIAlertAction
actionWithTitle:@"Save"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
[self save];
];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
[alertVC dismissViewControllerAnimated:YES completion:nil];
];
UIAlertAction *discardAction = [UIAlertAction
actionWithTitle:@"Discard"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
[alertVC dismissViewControllerAnimated:YES completion:nil];
];
[alertVC addAction:saveAction];
[alertVC addAction:cancelAction];
[alertVC addAction:discardAction];
[self.view.window.rootViewController presentViewController:alertVC animated:YES completion:nil];
这将对您有所帮助,因为它可以帮助我解决同样的问题。 以上代码兼容 ios 7 & 8
【讨论】:
最好使用 class/respondsToSelector:
检查而不是使用 iOS 版本号:***.com/questions/25111011/…
请勿调用 -[dismissViewControllerAnimated:completion:] 自行关闭。 UIAlertViewController 将在调用处理程序块之前或之后自行关闭。同时,直接访问alertVC会导致action
和alertController
之间的retain循环。不要问我为什么会意识到......【参考方案4】:
我也是,在关闭 UIAlertController 后弹出一个键盘(光标位于上次使用的 textView 中),这是一个非常简单的修复:
在构建和呈现 UIAlertController 之前,
使用 [_activeTextView resignFirstResponder];键盘将重新出现。 使用 [self.view endEditing:YES];键盘不会再次出现。
希望对你有帮助。
【讨论】:
此解决方案适用于 Swift 4。只是为了清楚起见:self.view.endEditing(true)【参考方案5】:尝试使用以下代码。它适用于 iOS 8 及以下版本
if (IS_OS_8_OR_LATER)
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg 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:^
];
else
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
【讨论】:
【参考方案6】:如果文本字段是第一响应者,则在解除警报时会自动弹出键盘。确保第一响应者被正确解雇:
[textField resignFirstResponder]
记住:在表格或滚动视图中,有时字段必须在屏幕上可见才能正确关闭响应者。
如果没有处于活动状态的第一响应者,则在解除警报时不应出现键盘。
对于这个问题的特殊情况,我建议设置一个委托方法来监听“完成”按钮并在委托回调中退出第一响应者。
或者,在开始编辑时,您可以存储对当前活动文本字段的引用,然后在“clickedButtonAtIndex”方法中,如果活动文本字段仍处于活动状态,您可以将其退出。
【讨论】:
您能否提供一个如何正确执行此操作的示例。我在滚动视图中没有它,但键盘似乎经常弹出。 [textField resignFirstResponder]【参考方案7】:我注意到 textField 键盘和 alertViews 的一些奇怪行为......也许可以创建一个名为 disableKeyboard 的布尔值并像这样使用它:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
if (disableKeyBoard)
disableKeyboard = NO;
return NO;
else
return YES;
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
disableKeyboard = YES;
这只是一种解决方法,并没有解决核心问题,无论它是什么。要使此方法起作用,您需要在标题中设置 alertView 和 textField 委托方法。
【讨论】:
textFieldShouldBeginEditing 在键盘闪烁时不会触发以上是关于在 iOS 8.3 for iPad 上关闭 UIAlertView 后键盘弹出的主要内容,如果未能解决你的问题,请参考以下文章
使用 UI 自动化以编程方式打开/关闭真实 iOS 设备上的 wifi
iOS 8.3 UIAlertController 在尝试添加文本字段时崩溃
在 iOS 8.3 中,UITabBarViewController 作为 UISplitViewController 的主控的问题