Question
I have several cases on iOS 11 (which are not found on iOS 10 and below) where the .UIKeyboardWillChangeFrame notification .UIKeyboardWillChangeFrame not start - especially when switching between view managers where both view controllers have a UIText field that is set to fristResponder.
Since I have a user interface that needs to be animated above the keyboard in response to the keyboard, receiving this notification is important.
On iOS 10 and below, I get a notification on both view controllers (when showing VC A, as well as when pressing VC B). However, on iOS 11, the notification does not work when you press VC B. It is as if the keyboard remained in place.
Does anyone know what is the reason for this?
More details
Both view controllers inherit from the base view controller with the following implementation:
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) } }
Subclass example:
class ViewControllerA: BaseViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) passwordField.becomeFirstResponder() } func relayout() {
Note that .keyboardWillShow and .keybaordWillHide also do not start when switching to VC B.
source share