小键盘不调用键盘通知

Keyboard notification not called with small keyboard

在我的代码中,当键盘变大时,键盘 open/close 的通知会被正常调用。但是一旦变小,将键盘挤压到手指之间,这些通知就不会再被调用了。有人有类似的问题吗?

这就是我观察通知的方式:

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillBeShown(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardDidShown(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillBeHidden(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

这是预期的行为。默认情况下,键盘会缩小屏幕尺寸,因此您必须挤压项目以使其适合。

但是当你“用手指挤压键盘”时,它开始漂浮在你的视图上,所以不再需要挤压。

您可以使用 UIResponder.keyboardWillChangeFrameNotification 获取键盘外观信息,如下所示:

func keyboardWillChangeFrame(_ notification: Notification) {
    guard
        let userInfo = notification.userInfo,
        let keyboardFrameEndRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
        let animationCurveOption = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int
    else { return }
    print(keyboardFrameEndRect, animationCurveOption)
    if keyboardFrameEndRect.isEmpty || // Floating keyboard is HIDING or BEING DRAGGED by the user
        keyboardFrameEndRect.origin.y >= UIScreen.main.bounds.height // Split keyboard is moving off screen
    {
        // When animation curve is zero, the keyboard is being hidden. (Otherwise, it's being moved)
        if animationCurveOption != 0 {
            print("KEYBOARD IS HIDING")
        } else {
            // e.g. ignore
            print("FLOATING KEYBOARD IS MOVING")
        }
    } else {
        print("KEYBOARD IS SHOWING")
    }
}

p.s。 UIResponder.keyboardWillChangeFrameNotification 遵循当前的 swift 语法而不是 NSNotification.Name.UIKeyboardWillChangeFrame

您还应该注册 UIResponder.keyboardFrameEndUserInfoKey(一个用户信息键,用于在动画结束时检索键盘的框架。)以观察键盘框架的变化。

notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

@objc func adjustForKeyboard(notification: Notification) {
    guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }

    let keyboardScreenEndFrame = keyboardValue.cgRectValue
    let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
     
    //You will get notifications event here
    if notification.name == UIResponder.keyboardWillHideNotification {
    
    } else {
   
    }
}

adjustForKeyboard() 方法有很多工作要做。首先,它将接收一个类型为 Notification 的参数。这将包括通知的名称以及包含名为 userInfo 的通知特定信息的字典。

使用键盘时,字典将包含一个名为 UIResponder.keyboardFrameEndUserInfoKey 的键,告诉我们键盘完成动画后的框架。这将是 NSValue 类型,而后者又是 CGRect 类型。 CGRect 结构包含 CGPoint 和 CGSize,因此它可用于描述矩形。