Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - UIAlertController hidden under keyboard

I have an UIAlertController presented from a UIViewController which is pushed in the UINavigationController as the last UIViewController. This UIAlertViewController has a UITextField in it.

My problem is that when I select the UITextField the keyboard shows up, but the UIAlertViewController stays centered, and partly hidden under the keyboard.

My code looks like this:

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

like image 658
beatrob Avatar asked Mar 04 '16 15:03

beatrob


2 Answers

It should be automatically be adjusted. Check you view hierarchy

like image 137
Cjay Avatar answered Nov 06 '22 18:11

Cjay


If I understood you, the problem is that alert is shown under keyboard. I think the problem is that the UIAlertController is shown on your viewController? but the keyboard is shown from rootViewController. Try this code to manage the problem

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)

I wrote extension, because in some cases the code above could not work

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
}

}

usage

    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)
like image 20
Alexandr Kolesnik Avatar answered Nov 06 '22 19:11

Alexandr Kolesnik