【问题标题】:How to determine UINavigationBar size before device orientation changes如何在设备方向更改之前确定 UINavigationBar 大小
【发布时间】:2015-03-22 05:08:10
【问题描述】:

我正在使用 Xcode 6 和 iOS 8 在 Objective-C 中编写一个应用程序。该应用程序需要能够部署在 iPhone 5、6 或 6+ 上。

如果您想直接回答我的问题,请跳到最后一句话。如果您想了解我为什么会提出这个问题,或者我可以如何更改我的 UI 布局以便以另一种方式解决我的问题,请继续阅读。

在我的一个视图控制器中,我有一个滚动视图,其顶部被限制在导航栏的底部,其底部被限制在表格视图的顶部。表格视图的底部被限制在视图控制器主视图的底部(即手机底部)。

滚动视图包含在用户点击时展开/收缩的子视图。我希望滚动视图随着其子视图的增长而增长,但显然我不希望滚动视图在屏幕外增长,因为它看起来很糟糕并且因为它会导致无法满足的约束(表格视图的顶部 - 被约束到底部滚动视图的 - 会在其底部下方交叉 - 被限制在主视图的底部......这会导致错误)。因此,我使用以下代码使滚动视图根据其子视图大小调整自身大小,而不会立即离开屏幕:

// The max height before the scroll view would go off screen, which would 
// mess up the table view's constraints and cause all sorts of problems
CGFloat maxHeight = self.view.size.height
                  - self.navigationController.navigationBar.frame.size.height
                  - [UIApplication sharedApplication].statusBarFrame.size.height;

// The height of all the subviews in the scroll view.
CGFloat height = _scrollContentView.frame.size.height;

if (height > maxHeight) {
    height = maxHeight;
}

self.scrollViewHeightConstraint.constant = height;

现在是有趣的部分。最初,每当我将设备从纵向旋转到横向时,我调用此代码来重新评估和重置滚动视图的大小,反之亦然。但是,当我将手机从纵向旋转到横向时,我遇到了约束错误。我确定这是因为我在 旋转之后调用此代码,此时主视图的高度较小,但滚动视图的高度仍然很大(导致表格视图的顶部低于底部,等等,正如我之前解释的那样)。所以,我只是将代码移动到 before 旋转(我在viewWillTransitionWithSize:withTransitionCoordinator: 方法中调用了代码)。到目前为止,这一切都说得通。

但是,现在的问题是导航栏的高度在发生旋转时会发生变化,但是viewWillTransitionWithSize:... 方法没有包含有关此更改的任何详细信息(它仅给出了主视图在旋转时的新大小已完成,而不是导航栏的新大小)。

所以,我需要以某种方式确定导航栏的新大小设备的方向实际改变之前(就像我可以在设备的方向实际改变之前使用 @ 来确定主视图的新大小一样987654324@方法)。

有什么想法吗?蒂亚!

【问题讨论】:

  • 据我了解,您需要获取 UINavigationBar 高度吗?
  • 什么意思?我在上面的代码中“获取”导航栏高度,但问题是在设备实际旋转并更新导航栏框架之前,该高度对于新方向是不正确的。我会在主视图中遇到同样的问题,除了 Apple 在预旋转方法 viewWillTransformWithSize:....在实际发生旋转之前。
  • 澄清一下:“预旋转”是指在设备方向实际完成更改之前,而“旋转后大小”是指在设备方向实际完成后项目的大小变化。

标签: ios uinavigationbar device-orientation


【解决方案1】:

所以,这是我最简单的解决方法:

/*
 * This method gets called when the device is about to rotate.
 */
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    // Set the scroll view's height to 0 to avoid constraints errors as described
    // in the question.
    self.scrollViewHeightConstraint.constant = 0;
}

/*
 * At the point when this method gets called, the device rotation has finished altering
 * the frames of the views in this view controller, but the layout has not finished
 * so nothing has changed on screen.
 */
- (void)viewWillLayoutSubviews
{
    // The max height before the scroll view would go off screen, which would mess up
    // the table view's constraints and cause all sorts of problems
    CGFloat maxHeight = self.view.size.height
                      - self.navigationController.navigationBar.frame.size.height
                      - [UIApplication sharedApplication].statusBarFrame.size.height;

    // The height of all the subviews in the scroll view.
    CGFloat height = _scrollContentView.frame.size.height;

    if (height > maxHeight) {
        height = maxHeight;
    }

    // Reset the scroll view's height to the appropriate height.
    self.scrollViewHeightConstraint.constant = height;

    [super viewWillLayoutSubviews];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    相关资源
    最近更新 更多