keyboardFrameEndUserInfoKey 没有显示正确的值?

keyboardFrameEndUserInfoKey not showing correct values?

我的视图底部有一个文本输入字段,我正在尝试对其进行上下动画处理以保持在键盘顶部。

func setupKeyboardObservers() {
    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillChangeFrame), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidShow), name: UIResponder.keyboardDidShowNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillChangeFrame), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func handleKeyboardWillChangeFrame(notification: NSNotification) {

    let keyboardFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
    let keyboardDuration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double)

    print(keyboardFrame)
    orderDetailView?.textInputViewBottomAnchor?.constant = -keyboardFrame!.height
    UIView.animate(withDuration: keyboardDuration!) {
        self.view.layoutIfNeeded()
    }
}

OrderDetailView 是 viewcontroller 的视图。

textinputview 是动画的部分,当键盘第一次出现时它工作正常,但当我发送消息并且键盘退出第一响应者时,它不会动画回来,如果我通过在键盘外部单击 reignifirstresponder 也不会.

当我从 keyboardFrameEndUserInfoKey 打印 cgrect 值时,它 returns 与键盘存在时相同的帧值(而不是 0)。

只有当我从视图中向下拖动键盘时,这似乎才能正常工作。

感谢您的帮助。

在你的情况下,当键盘隐藏时高度仍然不为零,我认为这是你的问题。您需要将键盘框架转换为您的视图坐标系并根据它设置约束。检查以下内容:

@objc private func onKeyboardChange(notification: NSNotification) {
    guard let info = notification.userInfo else { return }
    guard let value: NSValue = info[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
    let newFrame = value.cgRectValue

    if let durationNumber = info[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, let keyboardCurveNumber = info[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber {
        let duration = durationNumber.doubleValue
        let keyboardCurve = keyboardCurveNumber.uintValue
        UIView.animate(withDuration: duration, delay: 0, options: UIViewAnimationOptions(rawValue: keyboardCurve), animations: {
            self.updateFromKeyboardChangeToFrame(newFrame)
        }, completion: { _ in
            // After animation
        })
    } else {
        self.updateFromKeyboardChangeToFrame(newFrame)
    }
}

private func updateFromKeyboardChangeToFrame(_ keyboardFrame: CGRect) {
    let view: UIView! // Whatever view that uses bottom constraint
    let bottomConstraint: NSLayoutConstraint! // Your bottom constraint

    let constant = view.bounds.height-max(0, view.convert(keyboardFrame, from: nil).origin.y)
    bottomConstraint.constant = max(0, constant)
    view.layoutIfNeeded()
}

在你的情况下你似乎使用

let view = self.view
let bottomConstraint = orderDetailView?.textInputViewBottomAnchor

这取决于您如何定义约束,但您似乎需要使用负值作为 bottomConstraint.constant = -max(0, constant)