【问题标题】:Keyboard pops up after UIAlertView is dismissed on iOS 8.3 for iPad在 iOS 8.3 for iPad 上关闭 UIAlertView 后键盘弹出
【发布时间】: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。谢谢。

标签: ios ipad uialertview ios8.3


【解决方案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 版本号:stackoverflow.com/questions/25111011/…
  • 请勿调用 -[dismissViewControllerAnimated:completion:] 自行关闭。 UIAlertViewController 将在调用处理程序块之前或之后自行关闭。同时,直接访问alertVC会导致actionalertController之间的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 在键盘闪烁时不会触发
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    相关资源
    最近更新 更多