When a user taps a UITextField, the keyboard will come up. I scroll up the UITextField to sit just above the keyboard. This is working fine on iPhone:
- (void) someWhere
{
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onKeyboardShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
- (void) onKeyboardShow:(NSNotification *)notification
{
CGRect keyboardRect = [[[notification userInfo]
objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue
];
if (keyboardRect.size.height >= IPAD_KEYBOARD_PORTRAIT_HEIGHT) {
self.containerView.y = self.containerView.y - keyboardRect.size.width;
} else {
self.containerView.y = self.containerView.y - keyboardRect.size.height;
}
}
However, it is broken on iPad. On iPad, modal view controllers can be presented as a sheet that takes up only a portion of the screen. You can see that there is a gap between the last UITextField and the keyboard on iPad.
UINavigationController* nav = [[UINavigationController alloc]
initWithRootViewController:someRootViewController];
nav.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:nav animated:YES completion:nil];
I need to detect the offset of the modal view from the bottom of the screen and add that to the Y coordinate of the UITextField. This will make the UITextField flush with the top of the keyboard. Through some reverse engineering, I got the frame of the modal view by traversing undocumented view hierarchy:
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// describe is a category function on UIView that prints out the frame
[self.viewController.view.superview.superview.superview.superview describe];
}
x: 114.000000,
y: 192.000000,
w: 540.000000,
h: 620.000000
Finally, to get the offset of the modal view from the bottom of the screen, I do:
UIView* modalView = self.viewController.view.superview.superview.superview.superview;
// usage of self-explanatory UIView category methods
CGFloat bottomOffset = modalView.superview.height - (modalView.y + modalView.height);
To my chagrin, this only works in portrait mode. For some reason, the modal view's superview is always stuck with a width of 768 and height of 1024 no matter what orientation the iPad is in. So here is where I'm asking for help. How do I reliably get the offset of the modal view from the bottom of the screen, irregardless of the orientation, on iPad?