呈现Modal ViewController时的方向问题

时间:2014-05-29 15:17:03

标签: ios uiviewcontroller uiinterfaceorientation

当前情况:

现在我使用UIViewController使用样式segue和演示文稿Modal来展示Sheet。这个Modal得到它的superview边界变化,以便拥有我想要的尺寸,如下所示:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    self.view.superview.bounds = WHBoundsRect;
}

唯一允许的方向是UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRight。由于Modal有一些TextFields而且键盘会超过Modal本身,我正在更改它的center,所以它会移动到顶部。

问题:

我现在注意到的是,我无法使用Y坐标。为了让它垂直移动(记住它在横向上)我需要使用X.问题是当它是UIInterfaceOrientationLandscapeLeft时我需要带一个负X.而当它是UIInterfaceOrientationLandscapeRight时我需要为了得到一个正X.所以似乎X/Y Coordinate System被“粘在”左上角,而在纵向中,当一个方向发生时,它仍然存在:

enter image description here

我做了什么

所以我有这样的事情:

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
NSInteger newX = 0.0f;

if (orientation == UIInterfaceOrientationLandscapeLeft)
{
  // Logic for calculating the negative X.
}
else
{
  // Logic for calculating the positive X.
}

它的工作原理与我想要的完全一样,但它似乎是一个非常脆弱的实现。我错过了什么吗?这是预期的行为吗?

1 个答案:

答案 0 :(得分:1)

更新

我写了一个测试项目,你可以找到它here

这是有趣的部分,模态视图控制器子类代码。

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    self.view.superview.bounds = WHBoundsRect;
}

- (void)keyboardWillAppear:(NSNotification*)notification
{
    CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

    // Calculate keyboard frame in superview coordinates.
    // Origin will be in the upper left corner of the superview, so keyboard will have a negative x origin.
    CGRect keyboardFrameInSuperviewCoordinates = [self.view.superview convertRect:keyboardFrame fromView:nil];

    NSLog(@"Superview bounds: %@", NSStringFromCGRect(self.view.superview.bounds));
    NSLog(@"Keyboard frame in screen coordinates: %@", NSStringFromCGRect(keyboardFrame));
    NSLog(@"Keyboard frame in superview coordinates: %@", NSStringFromCGRect(keyboardFrameInSuperviewCoordinates));

    // The keyboard and the superview lay directly in a window, so we should do the math on window coordinates
    // Converting  to the superview system takes account of rotation, so now y is relative to current orientation
    CGRect windowCoordinatesInSuperviewSystem = [self.view.superview convertRect:self.view.superview.window.bounds fromView:nil];

    NSLog(@"Window frame in superview coords: %@", NSStringFromCGRect(windowCoordinatesInSuperviewSystem));


    // We calculate for how much the superview is hidden by the keyboard
    CGFloat hiddenPartHeight = CGRectGetMaxY(self.view.superview.bounds)-CGRectGetMinY(keyboardFrameInSuperviewCoordinates);
    NSLog(@"Superview is hidden by keyboard for %.0f points", hiddenPartHeight);

    // Now we just have to shift the superview frame to the top by 'hiddenPartHeight'.

    // Last step: calculate new superview frame in super-superview coordinate system.
    // To do that, we convert the superview frame relative to its coordinate system to super-superview coordinate system.
    CGRect superviewNewFrameInItsOwnCoordinateSystem = CGRectOffset(self.view.superview.bounds, 0, -hiddenPartHeight);
    CGRect superviewAbsoluteFrame = [self.view.superview convertRect:superviewNewFrameInItsOwnCoordinateSystem toView:self.view.superview.superview];

    NSLog(@"Superview new frame in its own coords: %@", NSStringFromCGRect(superviewNewFrameInItsOwnCoordinateSystem));
    NSLog(@"Superview new frame: %@", NSStringFromCGRect(superviewAbsoluteFrame));

    self.view.superview.frame = superviewAbsoluteFrame;
}