iOS 11 - 键盘通知返回的键盘高度为0

85

我一直在使用键盘通知,没有任何问题,并且可以精确获取键盘的高度。

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

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

iOS 11在通知栏弹出时,键盘的大小为0。

这种情况发生了什么问题?我正在使用Xcode 9 Beta 5。

8个回答

191

使用这个:

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

对于Swift,您可以使用:

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

5
将UIKeyboardFrameBeginUserInfoKey更改为UIKeyboardFrameEndUserInfoKey就可以了,谢谢。 - user2408952
@Akshay 只需在相应的屏幕边界中启动键盘的起始帧和结束帧。 - s.zainulabideen

102

UIKeyboardFrameBeginUserInfoKey 替换为

UIKeyboardFrameEndUserInfoKey

以下内容摘自 Apple 文档。

UIKeyboardFrameBeginUserInfoKey - 对象为 NSValue ,包含一个 CGRect,标识屏幕坐标中键盘的起始位置。

UIKeyboardFrameEndUserInfoKey - 对象为 NSValue ,包含一个 CGRect,标识屏幕坐标中键盘的结束位置。


13
苹果需要更新他们的示例代码,因为在iOS 11上它不再起作用。另外从苹果文档中可以看到,他们使用UIKeyboardFrameBeginUserInfoKey:https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html - wildcat12
解决了我的问题!感谢您的建议! - Ernie
有人能像我五岁一样解释一下这两者之间的区别,以及为什么在让UIScrollView自动滚动时这很重要吗?我真的会非常感激。谢谢! - Mario
在使用数字键盘输入后,文本框无法正常工作。如果在数字键盘后点击一般的文本框,键盘将不再弹出,当它被关闭时视图也会下移。 - Jack Daniel

7
尝试这样做:
UIKeyboardFrameEndUserInfoKey 替换 UIKeyboardFrameBeginUserInfoKey

1
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];方法keyboardWillChangeFrame:不仅会运行一次,可能会运行两次或更多。有时候,一些键盘在顶部有特殊的工具栏,此时该方法将运行多次。因此,您应该将UIKeyboardFrameBeginUserInfoKey替换为UIKeyboardFrameEndUserInfoKey以获取键盘的最终框架。 - SolinLiu

6

这个问题发生在iOS 11上。

"UIKeyboardFrameBeginUserInfoKey" 替换为 "UIKeyboardFrameEndUserInfoKey"

如下所示,可以解决该问题

Objective-C代码:

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

5

我曾经遇到过类似的问题,使用的是 Xcode 9.0 (9A235),但我在使用 Swift。在我的 keyboardWillShow 方法中,我写下了以下代码:

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

    let heightValue = keyboardSize.height    

    ...
}

很奇怪的是,第一次调用keyboardWillShow时,heightValue的值为216.0,但在后续调用中,它变成了0!可能这是Xcode的一个bug。

我用UIKeyboardFrameEndUserInfoKey替换了UIKeyboardFrameBeginUserInfoKey,这解决了我的问题。


1
我注意到了同样的事情。似乎只适用于键盘第一次显示的情况。在其他视图控制器上的键盘在第一次显示时报告高度为0。 - jackofallcode

4

使用以下代码计算键盘高度。

该代码适用于带有安全区域和非安全区域设备的两种设备。

代码:

@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
    }
}

2

您的方法是在显示之前尝试获取框架高度,这就是为什么它应该是0,但我不确定为什么第一次尝试时不是!以下是在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
}

在键盘出现之前,这将正确提供键盘框架属性。


0
尽管我们通过从安全区域调整底部空间约束来获取准确的键盘高度,但这会造成更多的空白空间。因此,如果我们要调整底部空间约束,就必须从安全区域边距中减去键盘高度。
    @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()
              }

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