在实际旋转之前确定导航栏的新框架 - iOS

4
我正在使用半透明的导航栏和状态栏,我的视图控制器需要全屏显示。因此,我的视图控制器的视图延伸到导航栏和状态栏下方,并占据了整个屏幕的大小。
我还有一个标签,我想将其直接对齐到导航栏下方。因为我不能直接在标签和导航栏之间添加约束,所以我在标签顶部和其父视图顶部之间添加约束。我将约束的常量设置为状态栏高度加上导航栏高度。
问题是,在纵向和横向之间旋转时,由于导航栏高度发生变化,我需要在 willRotateToInterfaceOrientation: 方法中知道导航栏的新高度,以确保标签能够正确旋转。
我使用这种方法来确保标签在从纵向或横向导航到视图控制器时位于正确的位置。它工作得很好。
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Get Y origin for Label
    CGFloat navBarY = self.navigationController.navigationBar.frame.origin.y;
    CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
    CGFloat labelY = navBarY + navBarHeight;

    // Set vertical space constraint for Label
    self.labelConstraint.constant = labelY;
}

当屏幕方向改变时,我使用这种方法重新定位标签,因为导航栏高度从44px变为32px。问题是,在实际旋转之前,我需要获取导航栏将要成为的新高度。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Get Y origin for Label
    CGFloat navBarY = self.navigationController.navigationBar.frame.origin.y;
    CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
    CGFloat labelY = navBarY + navBarHeight;


    // This obviously returns the the current Y origin for label before the rotation
    // Which isn't very useful.

    NSLog(@"labelY: %f", labelY);


    // This code produces the desired effect, but obviously I want to avoid
    // hard-coding the values.

    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
        self.labelConstraint.constant = 20 + 32;
    } else {
        self.labelConstraint.constant = 20 + 44;
    }
} 

为了好玩,我尝试在didRotateFromInterfaceOrientation:中旋转后设置标签的Y轴原点,但是如预期的那样,它并不平滑,标签在旋转完成后会突然跳到位。

提前感谢您的帮助!


你找到这个问题的答案了吗? - Jeanette Müller
我也遇到了同样的问题...有解决方案吗? - Ethan G
1个回答

0
答案是:尺寸类。您可以查阅苹果的文档了解更多信息。您需要使用以下函数:func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)。在设置视图时,我建议在您的视图控制器中添加两个属性,一个用于纵向模式,一个用于横向模式,都是NSLayoutConstraint数组。自iOS 8以来,有可能同时激活/停用多个约束条件。在上述提到的函数中,请执行以下操作:
if newCollection.verticalSizeClass == .Compact { //orientiation is landscape
    NSLayoutConstraint.deactivateConstraints(self.portraitConstraints)
    NSLayoutConstraint.activateConstraints(self.landscapeConstraints)
} else {
    NSLayoutConstraint.deactivateConstraints(self.landscapeConstraints)
    NSLayoutConstraint.activateConstraints(self.portraitConstraints)
}

请确保先停用,否则您的约束条件将会冲突。

抱歉回答有点“Swifty”,我想您应该能够将其“翻译”成 ObjC。如果您有任何问题,请随时提问。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接