For the constant UIKeyboardFrameEndUserInfoKey
, in the Apple docs it says:
These coordinates do not take into account any rotation factors
applied to the window’s contents as a result of interface orientation
changes. Thus, you may need to convert the rectangle to window
coordinates (using the convertRect:fromWindow: method) or to view
coordinates (using the convertRect:fromView: method) before using it.
So if I use [view1 convertRect:rect fromView:view2]
What would I insert for the above parameters to get it to convert the rotation values correctly? ie:
view1 = ?
rect = ? (the keyboard frame I'm assuming)
view2 = ?
Been trying some things and getting some funny stuff.
The first view should be your view. The second view should be nil, meaning window/screen coordinates. Thus:
NSDictionary* d = [notification userInfo];
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
r = [myView convertRect:r fromView:nil];
Now you have the rect that the keyboard will occupy, in terms of your view. If your view is the current view controller's view (or a subview thereof), rotation and so forth are now accounted for.
I tried the accepted answer and found that it does not actually provide the CGRect of the keyboard within the view. I found that I have to convert the CGRect from the UIScreen object to the UIWindow object, and from the UIWindow object to the UIView object:
NSValue * keyboardEndFrame;
CGRect screenRect;
CGRect windowRect;
CGRect viewRect;
// determine's keyboard height
screenRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
windowRect = [self.view.window convertRect:screenRect fromWindow:nil];
viewRect = [self.view convertRect:windowRect fromView:nil];
I use the above to resize the root view to not be hidden by the keyboard:
NSTimeInterval duration;
CGRect frame;
// determine length of animation
duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// resize the view
frame = self.view.frame;
frame.size.height -= viewRect.size.height;
// animate view resize with the keyboard movement
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:duration];
self.view.frame = frame;
[UIView commitAnimations];
+ (void)parseKeyboardNotification:(NSNotification *)notification
inRelationToView:(UIView *)view
info:(void(^)(NSTimeInterval keyboardAnimationDuration, CGRect keyboardFrameInView, UIViewAnimationOptions keyboardAnimationOptions))callback
{
NSParameterAssert(notification != nil);
NSParameterAssert(view != nil);
NSDictionary *userInfo = [notification userInfo];
UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
UIViewAnimationOptions animationOption = animationCurve << 16; // https://devforums.apple.com/message/878410#878410
NSTimeInterval animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// http://stackoverflow.com/a/16615391/202451
CGRect screenRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect windowRect = [view.window convertRect:screenRect fromWindow:nil];
CGRect viewRect = [view convertRect:windowRect fromView:nil];
callback(animationDuration, viewRect, animationOption);
}
Can be used like this
- (void)keyboardWillShowOrHide:(NSNotification *)notification
{
[AGKeyboardInfo parseKeyboardNotification:notification inRelationToView:self.view info:^(NSTimeInterval keyboardAnimationDuration, CGRect keyboardFrameInView, UIViewAnimationOptions keyboardAnimationOptions) {
[UIView animateWithDuration:keyboardAnimationDuration delay:0 options:keyboardAnimationOptions animations:^{
// do any modifications to your views
} completion:nil];
}];
}