My app uses a UIAccessoryView
to provide additional keyboard functionality (such as forward/backward tabs and arrows keys) for the virtual keyboard, but that causes
If you inspect the frame in UIKeyboardFrameEndUserInfoKey
you'll find that it is offset by the height of the keyboard when an external keyboard is attached (basically it does "appear", but never appears above the bottom of the screen), so you can convert it to your local coordinate space and intersect it with your view's bounds to find the visible height of the keyboard.
- (void)keyboardWillShow:(NSNotification *)notification {
UIView *view = [self view];
CGRect bounds = [view bounds];
CGRect keyboardFrame = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect convertedKeyboardFrame = [view convertRect:keyboardFrame fromView:nil];
CGRect intersection = CGRectIntersection(convertedKeyboardFrame, bounds);
// intersection.size.height == 0 with external keyboards
}
(This answer was suggested by Sean Heber on the Apple forums)
When you get a UIKeyboardDidShowNotification
, instead of using the frame given by UIKeyboardFrameEndUserInfoKey
, simply test where the view's accessory view is and use that, instead. All I do is check to see what the frame of the accessory view is and convert it to my own view's coordinate space. Then I can easily use that frame to decide what to do.
Note: When the on-screen keyboard is shown/hidden using the bluetooth keyboard's eject button, it seems that UIKit sends UIKeyboardDidShowNotification
again but not a UIKeyboardWillHideNotification
. This is also a confusing inconsistency, but the above workaround is still valid as the system will change the frame of the inputAccessoryView when it slides in the on-screen keyboard, so you can still adjust things accordingly.