简体   繁体   中英

iOS 11 - Keyboard Height is returning 0 in keyboard notification

I have been using Keyboard notifications without any problem and getting exact height of Keyboard.

- (void)keyboardDidShow:(NSNotification *) notification{
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    NSLog(@"%f",keyboardSize.height);}

but with iOS 11 the size of keyboard is 0 when the notification is called.

What is the problem occurring in this scenario? I am using xcode 9 Beta 5

Use this:

CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

For Swift, you can use:

let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size

Replace UIKeyboardFrameBeginUserInfoKey

with

UIKeyboardFrameEndUserInfoKey

The below is from Apple Docs.

UIKeyboardFrameBeginUserInfoKey- The key for an NSValue object containing a CGRect that identifies the start frame of the keyboard in screen coordinates.

UIKeyboardFrameEndUserInfoKey - The key for an NSValue object containing a CGRect that identifies the end frame of the keyboard in screen coordinates.

Try this:

Replace UIKeyboardFrameBeginUserInfoKey with UIKeyboardFrameEndUserInfoKey

I had a similar issue using Xcode Version 9.0 (9A235); although I was using Swift. In my keyboardWillShow method I wrote the following:

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {

    let heightValue = keyboardSize.height    

    ...
}

Strangely, the first time keyboardWillShow was called, heightValue was 216.0, but during subsequent calls it had become 0! Perhaps this is an Xcode bug.

I replaced the UIKeyboardFrameBeginUserInfoKey with a UIKeyboardFrameEndUserInfoKey, and it fixed the issue for me.

This issue is happening on iOS 11.

Replace

"UIKeyboardFrameBeginUserInfoKey" with "UIKeyboardFrameEndUserInfoKey"

as shown below would fix the issue

Objective-C Code :

CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

Swift 2.3 :

let keyboardSize = (NfnPsgVar.userInfo![UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue().size

Swift 3 :

let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size

Calculate keyboard height using the below code.

It is working for both devices with the safe area and non-safe area devices.

Code:

@objc func keyboardWillShow(notification: Notification) {
    guard let keyboardFrame = notification.userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
            return
        }    
    let keyboardHeight: CGFloat                    
    if #available(iOS 11.0, *) {
       let window = UIApplication.shared.keyWindow
       let bottomPadding = window?.safeAreaInsets.bottom ?? 0.0
       keyboardHeight = keyboardFrame.cgRectValue.height - bottomPadding
    } else {
       keyboardHeight = keyboardFrame.cgRectValue.height
    }
}

Your approach is trying to get the frame height before it is shown, and that is why it should be 0 which I am not sure why it is not at the first try! Here is an example of how to correctly get the keyboard height in swift 4.2:

func keyboardWillShow(notification: Notification) {

    guard let userInfo = notification.userInfo else { return }

    guard var keyboardFrame: CGRect = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }

    keyboardFrame = view.convert(keyboardFrame, from: nil)

    let keyboardHeight = keyboardFrame.height
}

This will correctly provide the keyboard frame properties BEFORE keyboard appears.

Eventhough we get accurate keyboard height when we adjust BottomSpace Constraints from SafeArea it makes more empty space. So we have to subtract safeArea margin from keyboard height if we are going to adjust the bottomSpace Constraints.

    @objc func keyBoardWillShow(notification: NSNotification) {
                  
    
                  if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
                      var bottomPadding: CGFloat = 0
                      //IF device is latest including iPhone x, it will have bottom padding as safeArea Insets. So we have to subtract that from REAL Keyboard HEIGHT.
                      if let window = UIApplication.shared.windows.first{
                        bottomPadding = window.safeAreaInsets.bottom
                      }
    
                      let keyboardRectangle = keyboardFrame.cgRectValue
                      let keyboardHeight = keyboardRectangle.height - bottomPadding
                      bottomSpaceConstraint.constant = keyboardHeight
                  }
                  self.view.layoutIfNeeded()
              }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM