Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert UIKeyboardFrameEndUserInfoKey to View or Window Coordinates

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.

like image 266
Ser Pounce Avatar asked Mar 14 '13 06:03

Ser Pounce


3 Answers

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.

like image 97
matt Avatar answered Oct 24 '22 13:10

matt


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];
like image 40
David M. Syzdek Avatar answered Oct 24 '22 15:10

David M. Syzdek


+ (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];
    }];
}
like image 1
hfossli Avatar answered Oct 24 '22 14:10

hfossli