Animating in sync with the iOS keyboard

Periscope Keyboard Animation

After the status bar and rotation, the keyboard might be the finickiest part of iOS development.

It varies in height disproportionately to screen size, can be changed by the user mid-session, and the predictive suggestions bar introduced in iOS 8 can be shown, collapsed or disabled completely. Then there’s the iPad…

But height is really just the start. The real fun is in the keyboard’s custom show/hide animation.

It’s undocumented by Apple, yet you need its specifications if you want to appear to stick something to the keyboard - most commonly a text field for commenting or replying, as seen pretty much everywhere.

For a very rough approximation, you can trigger a 0.3s UIViewAnimationOptionCurveEaseOut animation whenever becomeFirstResponder is called. That’s what Apple’s engineers opted for in Apple Music’s Connect section:

Apple Music Keyboard Animation

As you can see, it’s off, and could get worse if Apple changed the animation in an upcoming release.

For exact results:

  • Register for UIKeyboardWillShowNotification:
// Register for UIKeyboardWillShowNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
  • Update properties with the very latest keyboard height, animation duration and curve values every time the keyboard is about to show:
- (void)keyboardWillShow:(NSNotification*)notification
    // Get keyboard height, animation duration and curve
    _keyboardHeight = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;
    _keyboardAnimationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    _keyboardAnimationCurve = [[[notification userInfo] objectForKey: UIKeyboardAnimationCurveUserInfoKey] integerValue];
  • Set these property values as your animation options. Because we’re dealing with a UIViewAnimationCurve rather than a UIViewAnimationOptions value, we have to use the old animation style instead of the preferred block-based method. Here I’m raising a transparent text field from the bottom of the screen to just above the keyboard, in sync:
// Apply the keyboard's animation specs to the textfield's animation, and commit
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:_keyboardAnimationDuration];
[UIView setAnimationCurve:_keyboardAnimationCurve];
[UIView setAnimationBeginsFromCurrentState:YES];

self.textField.frame = CGRectOffset(self.textField.frame, 0.0, _keyboardHeight);

[UIView commitAnimations];

RateIt Keyboard Animation

Thanks to Tim Johnsen for reviewing.