【问题标题】:Orientation issue while presenting Modal ViewController呈现模态视图控制器时的方向问题
【发布时间】:2014-05-30 04:44:40
【问题描述】:

当前情景:

现在我正在展示一个UIViewController,使用一个segue,样式为Modal,演示文稿Sheet。这个模态得到它的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 似乎在纵向时“粘”在左上角,当出现方向时,它仍然存在:

我做了什么

所以我有这样的事情:

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.
}

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

【问题讨论】:

  • 你能解释一下你为什么要这样做 self.view.superview.bounds = WHBoundsRect;?
  • @AlessandroOrrù "这个 Modal 改变了它的 superview 边界,以便获得我想要的尺寸"
  • 知道了,没看到模态视图和容器UIWindow之间有一个大小相同的超级视图

标签: ios uiviewcontroller uiinterfaceorientation


【解决方案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;
}

【讨论】:

  • 我明白了,我在这里使用self.view.window.view CGRect superviewAbsoluteFrame = [self.view.superview convertRect:superviewNewFrameInItsOwnCoordinateSystem toView:self.view.superview.superview]; 而不是self.view.superview.superview
  • 你也可以选择CGRectIntersection(self.view.superview.bounds, keyboardFrameInSuperviewCoordinates);
  • @JackyBoy 是的,我同意,但它们有点不同。使用我的解决方案,如果视图太小(因此矩形不相交),它无论如何都会连接到键盘(所以推到底部)。如果 CGRectIntersection 太小,它会保持静止。选择您最喜欢的解决方案 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多