I've got a view controller showing a view with a UITextView, and I want to resize the view when the keyboard appears so that the UITextView isn't covered by the keyboard. I have this working correctly in almost all cases. I'm still seeing some weirdness on the iPad, only when the view controller is presented in ModalPresentationStyleFormSheet, and only in LandscapeRight orientation, as far as I can tell.
Relevant parts of my view controller's -keyboardWillShow:
// We'll store my frame above the keyboard in availableFrame
CGRect availableFrame = self.view.frame;
// Find the keyboard size
NSDictionary *userInfo = [notification userInfo];
NSValue keyboardFrameScreenValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameScreen = [keyboardFrameScreenValue CGRectValue];
CGRect keyboardFrame = [self.view convertRect:keyboardFrameScreen fromView:nil];
CGSize keyboardSize = keyboardFrame.size;
// Figure out how much of my frame is covered by the keyboard
CGRect screenBounds = [self.view convertRect:[UIScreen mainScreen].bounds
fromView:nil];
CGRect myBoundsScreen = [self.view boundsInWindow]; // See below
CGFloat myBottom = myBoundsScreen.origin.y + myBoundsScreen.size.height;
CGFloat keyboardTop = screenBounds.size.height - keyboardSize.height;
CGFloat lostHeight = myBottom - keyboardTop;
availableFrame.size.height -= lostHeight;
-[UIView boundsInWindow]:
- (CGRect)boundsInWindow {
UIInterfaceOrientation orientation =
[UIApplication sharedApplication].statusBarOrientation;
CGRect bounds = [self convertRect:self.bounds toView:self.window];
if (UIInterfaceOrientationIsLandscape(orientation)) {
// Swap origin
CGFloat x = bounds.origin.y;
bounds.origin.y = bounds.origin.x;
bounds.origin.x = x;
// Swap size
CGFloat width = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = width;
}
return bounds;
}
This works, most of the time. When my app is in user interface orientation LandscapeRight though, the origin I get from -boundsInWindow is quite a bit lower than it should be. What could be causing this?
Thanks for any assistance!
Will's answer was the right idea but I had to tweak it quite a bit to get it right
I think I've found a pretty decent answer. You can use the
convertRect:fromView:
method onUIView
to convert coordinate systems.In swift code, the selector that UIKeyboardNotification calls look something like this:
Here's how I'm handling the keyboard with iPad form sheets:
Category on UIView: