【问题标题】:UIKeyboardWillChangeFrame not called on iOS 11 (when transitioning view controllers)iOS 11 上未调用 UIKeyboardWillChangeFrame(转换视图控制器时)
【发布时间】:2018-03-03 19:10:38
【问题描述】:

问题

我在 iOS 11 上有很多情况(在 iOS 10 及更低版本上不会发生).UIKeyboardWillChangeFrame 通知没有被触发——特别是在两个视图控制器都有一个 UITextfield 设置为的视图控制器之间转换时第一个响应者。

由于我的 UI 需要在键盘上方显示动画以响应键盘显示,因此接收此通知是必不可少的。

在 iOS 10 及更低版本上,我在两个视图控制器上都收到通知(在显示 VC A 时以及在推送 VC B 时)。但是,在 iOS 11 上,推送 VC B 时不会触发通知。就好像键盘保持在原位一样。

有人知道这是什么原因吗?


详情

两个视图控制器都从具有以下实现的基本视图控制器继承:

class BaseViewController {
override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: .UIKeyboardWillChangeFrame, object: nil)

}

// Update layout when the keyboard is shown or hidden
@objc func keyboardWillChangeFrame(notification : Notification) {

    // Check if got info
    if (notification.userInfo == nil) {
        return;
    }

    // Get resize properties
    let dict = notification.userInfo!
    let rect = self.view.convert((((dict[UIKeyboardFrameEndUserInfoKey as NSObject] as Any) as AnyObject).cgRectValue)!, from: nil)
    let size = self.view.bounds.size.height - rect.origin.y
    let duration = ((dict[UIKeyboardAnimationDurationUserInfoKey] as Any) as AnyObject).doubleValue
    let curve = UIViewAnimationCurve.init(rawValue: (((dict[UIKeyboardAnimationCurveUserInfoKey] as Any) as AnyObject).intValue)!)
    self.keyboardOffset = max(0, size)

    // Set animation options
    var options : UIViewAnimationOptions
    switch (curve!) {
    case .easeInOut:
        options = UIViewAnimationOptions()
    case .easeIn:
        options = UIViewAnimationOptions.curveEaseIn
    case .easeOut:
        options = UIViewAnimationOptions.curveEaseOut
    case .linear:
        options = UIViewAnimationOptions.curveLinear
    }

    // Animate the change
    UIView.animate(withDuration: duration!, delay: 0, options: options, animations: { () -> Void in

        // Relayout
        self.relayout()

    }, completion: nil)

}
}

子类示例:

class ViewControllerA: BaseViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        passwordField.becomeFirstResponder()
    }

    func relayout() {
    // ... do animations to show stuff above keyboard.
    }

}

请注意,.keyboardWillShow.keybaordWillHide 在转换到 VC B 时也不会触发。

【问题讨论】:

标签: ios swift uikeyboard


【解决方案1】:

您需要在您的第一个视图控制器的viewWillDisappear 方法中添加self.view.endEditing(force:Bool)

一般来说,换屏时可以随时调用endEditing方法。

【讨论】:

  • 这行得通,谢谢,但有隐藏然后重新显示键盘的副作用。
【解决方案2】:

我通过将键盘高度保存在 VC A 中的类变量中然后将其传递给 VC B 来解决此问题。 这并不理想,因为我希望我的 VC 对这些细节保持独立。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    相关资源
    最近更新 更多