can't get correct value of keyboard height in iOS8

Eli Braginskiy picture Eli Braginskiy · Sep 16, 2014 · Viewed 63.1k times · Source

I was using this code to determine what is the size of the keyboard :

- (void)keyboardWillChange:(NSNotification *)notification {
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];

}

I'm running this in the simulator.

The problem is since iOS 8 this will not give the correct value, if the keyboard suggestions is up or if I push them down I get different (not correct) values.

How can I get the exact size of the keyboard including the keyboard suggestions?

Answer

dgangsta picture dgangsta · Sep 23, 2014

With the introduction of custom keyboards in iOS, this problem becomes a tad more complex.

In short, the UIKeyboardWillShowNotification can get called multiple times by custom keyboard implementations:

  1. When the Apple system keyboard is opened (in portrait)
    • UIKeyboardWillShowNotification is sent with a keyboard height of 224
  2. When the Swype keyboard is opened (in portrait):
    • UIKeyboardWillShowNotification is sent with a keyboard height of 0
    • UIKeyboardWillShowNotification is sent with a keyboard height of 216
    • UIKeyboardWillShowNotification is sent with a keyboard height of 256
  3. When the SwiftKey keyboard is opened (in portrait):
    • UIKeyboardWillShowNotification is sent with a keyboard height of 0
    • UIKeyboardWillShowNotification is sent with a keyboard height of 216
    • UIKeyboardWillShowNotification is sent with a keyboard height of 259

In order to handle these scenarios properly in one code-line, you need to:

Register observers against the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification notifications:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];    
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];

Create a global variable to track the current keyboard height:

CGFloat _currentKeyboardHeight = 0.0f;

Implement keyboardWillShow to react to the current change in keyboard height:

- (void)keyboardWillShow:(NSNotification*)notification {
   NSDictionary *info = [notification userInfo];
   CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
   CGFloat deltaHeight = kbSize.height - _currentKeyboardHeight; 
   // Write code to adjust views accordingly using deltaHeight
   _currentKeyboardHeight = kbSize.height;
}

NOTE: You may wish to animate the offsetting of views. The info dictionary contains a value keyed by UIKeyboardAnimationDurationUserInfoKey. This value can be used to animate your changes at the same speed as the keyboard being displayed.

Implement keyboardWillHide to the reset _currentKeyboardHeight and react to the keyboard being dismissed:

- (void)keyboardWillHide:(NSNotification*)notification {
   NSDictionary *info = [notification userInfo];
   CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
   // Write code to adjust views accordingly using kbSize.height
   _currentKeyboardHeight = 0.0f;
}