title: UIKeyboardWillChangeFrame not called on iOS 11 (when transitioning view controllers)
body: <h3>Issue</h3>
  
  <p>I have a number of cases on iOS 11 (that do not occur on iOS 10 and below) where <code>.UIKeyboardWillChangeFrame</code> notification is not being fired — specifically when transitioning between view controllers where both view controllers have a UITextfield which is set as the fristResponder. </p>
  
  <p>Since I have UI that needs to animate above the keyboard in response to the keyboard showing, receiving this notification is essential.</p>
  
  <p>On iOS 10 and below, I get the notification on both view controllers (on showing VC A and also when pushing VC B). However, on iOS 11, the notification does not fire when pushing VC B. It's as if the keyboard remained in place.</p>
  
  <p>Does anyone know what the cause of this is?</p>
  
  <hr>
  
  <h3>Details</h3>
  
  <p>Both view controllers inherit from a base view controller with the following implementation:</p>
  
  <pre><code>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: { () -&gt; Void in
  
          // Relayout
          self.relayout()
  
      }, completion: nil)
  
  }
  }
  </code></pre>
  
  <p>Example of a subclass:</p>
  
  <pre><code>class ViewControllerA: BaseViewController {
  
      override func viewWillAppear(_ animated: Bool) {
          super.viewWillAppear(animated)
  
          passwordField.becomeFirstResponder()
      }
  
      func relayout() {
      // ... do animations to show stuff above keyboard.
      }
  
  }
  </code></pre>
  
  <p>Note that <code>.keyboardWillShow</code> and <code>.keybaordWillHide</code> are also not fired on the transition to VC B.</p>