UIKeyboardWillChangeFrame is not called on iOS 11 (when switching to view controllers)

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() { // ... do animations to show stuff above keyboard. } } 

Note that .keyboardWillShow and .keybaordWillHide also do not start when switching to VC B.

+5
source share
2 answers

You need to add self.view.endEditing(force:Bool) to your first viewWillDisappear controller controller.

Typically, you can always call the endEditing method when the screen changes.

0
source

I worked on this by storing the keyboard height in a class variable in VC A and then passing it to VC B. This is not ideal, as I would prefer my VC to be independent of these details.

0
source

Source: https://habr.com/ru/post/1272033/


All Articles