iPhoneX and iPhone 8 keyboard height are different

William Hu picture William Hu · Sep 26, 2017 · Viewed 16.5k times · Source

I use below code to get keyboard height. Then use this height to calculate the frame of an UIView to make sure this UIView just on the top of the keyboard.

But in iPhoneX simulator the output is 333 and the iPhone 8 simulator is 258.

ISSUE: If use rect.height as the keyboard height for iPhone 8 simulator then the layout is correct. For iPhone X there's a gap between the UIView and keyboard. Which means 333 is higher than the real keyboard height in iPhone X.

What's the reason of the height are different? And how to get the correct keyboard height?

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)


@objc func keyboardWillShow(_ notification: NSNotification) {
        if let rect = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
           print(rect.height)
        } 
    }

Like this image, the green border should be the extra part. Actually, I need the red part just on the top of keyboard without the green rect gap. enter image description here

EDIT

OK, with @Craig's help I found this method only called by iPhone X. So I update frame here. Just paste the code here.

The safe area bottom height is 22.0 seems not correct.

override func viewSafeAreaInsetsDidChange() {
    if #available(iOS 11.0, *) {
        super.viewSafeAreaInsetsDidChange()
        view.safeAreaInsets.bottom // This value is the bottom safe area place value.
    }
}

EDIT2 Normally view.safeAreaInsets.bottom should be 34.0, but if you are using container view this value can be different like mine is 22.0.

Answer

Kqtr picture Kqtr · Feb 8, 2018

While Craig's answer is correct, you might not want to pin your view to view.bottom or the bottomLayoutGuide rather than the safe area bottom (especially if your keyboard is not always open, and you don't want your views to cover the Home Indicator area).

Here is a fix for these cases. It deducts the height of the bottom inset of the safe area from the height of the keyboard:

var keyboardHeight = ... // Get the keyboard height from keyboard notification

if #available(iOS 11.0, *) {
    let bottomInset = view.safeAreaInsets.bottom
    keyboardHeight -= bottomInset
}