如何计算iPad上模态视图的底部偏移量?

时间:2013-09-13 00:17:50

标签: ios ipad cocoa-touch modalviewcontroller

当用户点击UITextField时,键盘会出现。我向上滚动UITextField以便位于键盘上方。这在iPhone上运行良好:

enter image description here

- (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;        
    }
}

然而,它在iPad上被破坏了。在iPad上,模态视图控制器可以显示为仅占用屏幕一部分的工作表。您可以看到最后一个UITextField与iPad上的键盘之间存在差距。

enter image description here

UINavigationController* nav = [[UINavigationController alloc]
    initWithRootViewController:someRootViewController];
nav.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:nav animated:YES completion:nil];

我需要从屏幕底部检测模态视图的偏移量,并将其添加到UITextField的Y坐标。这将使UITextField与键盘顶部齐平。通过一些逆向工程,我通过遍历未记录的视图层次结构得到了模态视图的框架:

- (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

最后,为了从屏幕底部获取模态视图的偏移量,我这样做:

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

令我懊恼的是,这只适用于纵向模式。出于某种原因,无论iPad处于什么方向,模态视图的超视图总是卡在768的宽度和1024的高度。所以这里是我要求帮助的地方。如何在iPad上可靠地从屏幕底部获取模态视图的偏移量,无论其方向如何?

2 个答案:

答案 0 :(得分:1)

我看到两种可能的解决方案:

  1. 使用inputAccessoryView自动将文本字段附加到键盘。

  2. 将键盘rect转换为您尝试移动的containerView的superview。然后,您可以在containerView的superview 的坐标中获取其顶部Y值

  3. 类似的东西:

    CGRect rectInWindowCoordinates = [self.containerView.window convertRect:keyboardRect fromWindow:nil];
    CGRect rectCoveredByKeyboard = [self.containerView.superview convertRect:rectInWindowCoordinates fromView:nil];
    CGFloat top = CGRectGetMinY(rectCoveredByKeyboard);
    self.containerView.y = top - self.containerView.frame.size.height;
    

答案 1 :(得分:0)

- (void) onKeyboardShow:(NSNotification *)notification
{
    CGRect keyboardRect = [[[notification userInfo] 
        objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue
    ];    

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

    // The keyboard height is only correct when in portrait mode. To get the
    // real height, we make the assumption that keyboards are always wider than
    // they are tall.
    CGFloat keyboardHeight;
    if (keyboardRect.size.width < keyboardRect.size.height) {
        keyboardHeight = keyboardRect.size.width;
    } else {
        keyboardHeight = keyboardRect.size.height;
    }

    CGPoint originOfKeyboardInWindowContext;

    switch (orientation) {
        //
        // (0,0) ___________
        //      |           |
        //      |           |
        //      |           |
        //      |           |
        //      |           |
        //      |===========|
        //      |===========|
        //
        case UIInterfaceOrientationPortrait:
            originOfKeyboardInWindowContext = CGPointMake(0.0, [VeetleAppDelegate instance].window.height - keyboardHeight);
            break;
        //
        //       ___________
        //      |           |
        //      |           |
        //      |           |
        //      |           |
        //      |           |
        //      |===========|
        //      |===========| (0,0)
        //
        case UIInterfaceOrientationPortraitUpsideDown:
            originOfKeyboardInWindowContext = CGPointMake(0.0, keyboardHeight);
            break;
        //
        //       _________________
        //      |                 |
        //      |                 |
        //      |                 |
        //      |=================|
        //      |=================|
        // (0,0)
        //
        case UIInterfaceOrientationLandscapeRight:
            originOfKeyboardInWindowContext = CGPointMake(keyboardHeight, 0.0);
            break;
        //
        //       _________________  (0,0)
        //      |                 |
        //      |                 |
        //      |                 |
        //      |=================|
        //      |=================|
        //
        case UIInterfaceOrientationLandscapeLeft:
            originOfKeyboardInWindowContext = CGPointMake([VeetleAppDelegate instance].window.width - keyboardHeight, 0.0);
            break;
    }

    CGPoint originOfKeyboardInTextFieldContext = [[VeetleAppDelegate instance].window convertPoint:originOfKeyboardInWindowContext toView:self.containerView.superview];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    self.containerView.y = originOfKeyboardInTextFieldContext.y - self.containerView.height;
    [UIView commitAnimations];
}