iOS - UIAlertController被键盘遮挡了

9
我有一个UIAlertController从一个UIViewController弹出,这个UIViewController在UINavigationController中作为最后一个UIViewController被推入。这个UIAlertViewController里面有一个UITextField。
我的问题是当我选择UITextField时,键盘会弹出,但是UIAlertViewController仍然居中,并且部分被键盘遮挡。
我的代码如下:
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Enter Your PIN" message:@"Please enter your PIN!" preferredStyle:UIAlertControllerStyleAlert];

[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        [textField setSecureTextEntry:YES];
    }];

UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"Confirm"
                                                       style:UIAlertActionStyleDefault
                                                     handler:^(UIAlertAction * _Nonnull action) {  }];


UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
                                                           style:UIAlertActionStyleCancel
                                                         handler:^(UIAlertAction * _Nonnull action) {
                                                         }];
[alert addAction:okAction];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];

ScrenshotHidden UIAllertController


这是在模拟器中还是在真实设备上? - alfreedom
真实设备,带有最新的iOS。 - beatrob
你有没有类似于“Unbalanced calls to begin/end appearance transitions for <ViewController>”这样的消息? - Joe Daniels
1
我建议在使用 UAlertController 时隐藏键盘。或者使用自定义的 alertcontroller - jhd
我遇到了与以下场景完全相同的问题:1)按照上述描述呈现UIAlertViewController。这个没问题。2)停用应用程序,例如打开另一个应用程序。3)重新激活应用程序。键盘消失了,必须通过点击文本字段再次激活。现在对话框在键盘下面呈现。 - Ely
显示剩余2条评论
6个回答

5

应该自动进行调整。 检查您的视图层次结构


beatrob,我已经尝试了你的代码,没有做任何更改,它会自动调整,就像“cjay”所说的那样。 - Er. Vihar
现状良好,无需更改。可能是iOS的一个错误。 - sweta.me

1
如果我理解正确的话,问题是警告框显示在键盘下面。我认为问题在于 UIAlertController 显示在您的 viewController 上?但是键盘是从 rootViewController 显示的。尝试使用此代码来解决问题。
let alert = UIAlertController(title: "Title", message: NSLocalizedString("Message", comment: ""), preferredStyle: .alert)
                let okAction = UIAlertAction(title: "OK", style: .default) { action in }
alert.addAction(okAction)
let rootViewController: UIViewController = UIApplication.shared.windows.last!.rootViewController!
rootViewController.present(alert, animated: true, completion: nil)

我写了一个扩展,因为在某些情况下上述代码可能无法正常工作。
extension UIApplication {

class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
    if let nav = base as? UINavigationController {
        return topViewController(base: nav.visibleViewController)
    }
    if let tab = base as? UITabBarController {
        let moreNavigationController = tab.moreNavigationController
        if let top = moreNavigationController.topViewController, top.view.window != nil {
            return topViewController(base: top)
        } else if let selected = tab.selectedViewController {
            return topViewController(base: selected)
        }
    }
    if let presented = base?.presentedViewController {
        return topViewController(base: presented)
    }
    return base
}

}

使用
    let alert = UIAlertController(title: NSLocalizedString(title, comment: ""), message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
    UIApplication.topViewController()?.present(alert, animated: true, completion: nil)

对我来说没有起作用。我猜这应该是iOS的一个bug。 - Yuichi Kato
回答已编辑,请尝试一下,在我的情况下完美运行。 - Alexandr Kolesnik
你有检查 topViewController 的返回值吗? - Alexandr Kolesnik

0

键盘显示在一个专用的窗口中。警告框也是如此,您的视图控制器(请参阅应用委托的window属性)等等。它是UIWindow实例的windowLevel决定了窗口的Z顺序(即窗口如何在彼此之上/之下呈现)。

我们在使用自定义窗口自定义警告时,在我们的应用程序中看到了相同的行为,该窗口总是显示在键盘的窗口之下。在iOS 9/10版本发布的某个时候,窗口级别的行为似乎发生了变化,以便键盘的窗口始终位于窗口堆栈的顶部。

由于UIAlertController的窗口由系统管理,第三方开发者可能没有办法修改这种行为。

然而,要检查警告窗口的窗口级别,您可以在呈现完成块中引用其viewwindowwindowLevel属性(例如在呈现函数的完成块中)。甚至可以尝试将其更改为非常大的值,以强制警告窗口的级别。

要跟踪此问题,您可以复制this radar


0

您可以添加[self.view endEditing:YES];以确保键盘不会显示。


1
在没有键盘的情况下,有人如何在此框中输入他们的PIN码? - David Rector

0

-3
You can manage your keyboard based on textField location.


// Call this method somewhere in your view controller in **viewdidload** method

    - (void)registerForKeyboardNotifications
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(keyboardWasShown:)
                name:UIKeyboardDidShowNotification object:nil];

       [[NSNotificationCenter defaultCenter] addObserver:self
                 selector:@selector(keyboardWillBeHidden:)
                 name:UIKeyboardWillHideNotification object:nil];

    }

//Add in your View Controller which Called when the UIKeyboardDidShowNotification is sent.

    - (void)keyboardWasShown:(NSNotification*)aNotification
    {
        NSDictionary* info = [aNotification userInfo];
        CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

        UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;

        // If active text field is hidden by keyboard, scroll it so it's visible
        // Your app might not need or want this behavior.
        CGRect aRect = self.view.frame;
        aRect.size.height -= kbSize.height;
        if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
            [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
        }
    }
// Add in your View Controller which Called when the UIKeyboardWillHideNotification is sent

    - (void)keyboardWillBeHidden:(NSNotification*)aNotification
    {
        UIEdgeInsets contentInsets = UIEdgeInsetsZero;
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;
    }

Initialize UITextField * activeField;

Additional methods for tracking the active text field.

    - (void)textFieldDidBeginEditing:(UITextField *)textField
    {
        activeField = textField;
    }

    - (void)textFieldDidEndEditing:(UITextField *)textField
    {
        activeField = nil;
    }

您还可以在苹果文档中查看这些概念。 https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接