28

对于常量UIKeyboardFrameEndUserInfoKey,在 Apple 文档中它说:

这些坐标不考虑由于界面方向更改而应用于窗口内容的任何旋转因素。因此,在使用它之前,您可能需要将矩形转换为窗口坐标(使用 convertRect:fromWindow: 方法)或视图坐标(使用 convertRect:fromView: 方法)。

所以如果我使用[view1 convertRect:rect fromView:view2]

我将为上述参数插入什么以使其正确转换旋转值?IE:

视图1 = ? 矩形 = ? (我假设的键盘框架) view2 = ?

一直在尝试一些事情并得到一些有趣的东西。

4

3 回答 3

69

第一个视图应该是您的视图。第二个视图应该为零,表示窗口/屏幕坐标。因此:

NSDictionary* d = [notification userInfo];
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
r = [myView convertRect:r fromView:nil];

现在,就您的视图而言,您有了键盘将占据的矩形。如果您的视图是当前视图控制器的视图(或其子视图),则现在考虑旋转等。

于 2013-03-22T03:05:45.913 回答
23

我尝试了接受的答案,发现它实际上并没有在视图中提供键盘的 CGRect 。我发现我必须将 CGRect 从 UIScreen 对象转换为 UIWindow 对象,并从 UIWindow 对象转换为 UIView 对象:

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];

我使用上面的方法来调整根视图的大小,使其不被键盘隐藏:

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];
于 2013-05-17T18:10:01.607 回答
1
+ (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);
}

可以这样使用

- (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];
    }];
}
于 2014-01-22T13:31:20.143 回答