Topics

#82: Keyboard Notifications πŸ””

Topics

iOS's software keyboard has evolved quite a bit over the years. Just last week we saw a new variant of it on the new iPad Pro. The user can also connect a hardware keyboard at anytime, hiding the software one. It's important, now more than ever, that we not make any assumptions about how and when the keyboard will transition on and off the screen.

It'd be great if the system could tell us all the details of how and where it's about to animate. Then we could use that info to move our own controls and views right alongside it. For this we can listen for some keyboard notifications_, and react appropriately. Let's take a look.

We'll start by registering for two notifications in viewDidLoad:

NSNotificationCenter.defaultCenter().addObserver(self,
  selector: "keyboardWillShowOrHide:", name: UIKeyboardWillShowNotification, object: nil)

NSNotificationCenter.defaultCenter().addObserver(self,
  selector: "keyboardWillShowOrHide:", name: UIKeyboardWillHideNotification, object: nil)

Fun fact: Starting in iOS 9, we don't need to unregister these in deinit, the system now does it for us! πŸŽ‰

Next, we'll grab all the necessary values out of the notification's userInfo, and use them to animate our own views exactly alongside the keyboard as it slides on or off the screen:

func keyboardWillShowOrHide(notification: NSNotification) {
  let i = notification.userInfo!
  let start = view.convertRect(i[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue(), fromView: view.window)
  let end = view.convertRect(i[UIKeyboardFrameEndUserInfoKey]!.CGRectValue(), fromView: view.window)

  bottomConstraint.constant -= (end.origin.y - start.origin.y)
  view.setNeedsUpdateConstraints()

  let duration = i[UIKeyboardAnimationDurationUserInfoKey]!.doubleValue

  UIView.animateWithDuration(duration, delay: 0, options: .BeginFromCurrentState, animations: {
    self.view.layoutIfNeeded()
  }, completion: nil)
}

We grab the start and end frames, convert them to our view controller's view's coordinate space, and use the difference to move a constraint. Then we animate the constraint like we covered Bite #9.