【问题标题】:Force the navigation bar to add space for the status bar强制导航栏为状态栏添加空间
【发布时间】:2018-07-30 12:29:45
【问题描述】:

我有一个UIPageViewController 子类,它允许用户从初始视图控制器向上滑动到第二个视图控制器。初始视图控制器没有导航栏(它没有连接到UINavigationController),但第二个有。目前,当我向上滑动以呈现第二个视图控制器时,导航栏中没有空间用于状态栏。过渡完成后,整个视图控制器布局会立即更新以添加状态栏空间。我想让第二个视图控制器预计状态栏会在那里并为其添加空间,以便视图在转换后不会摇晃。

Short video clip showing the jolt

Similar, but unanswered question

编辑:

在仔细观察了视图控制器在转换过程中的行为方式之后,我能够很好地了解这里发生了什么。

  1. 当我向上滑动时,第二个视图控制器向上移动并将导航栏(无状态栏)的顶部边缘与屏幕顶部对齐。看起来内容的大小/布局是正确的,所以底部有空格,即状态栏的高度。查看屏幕截图:

  1. 过渡完成后,状态栏的空间被添加,视图向下移动。

【问题讨论】:

标签: ios swift uinavigationbar statusbar uipageviewcontroller


【解决方案1】:

我找到了一个似乎效果很好的解决方法。我需要用 iPhone X 对此进行测试,看看是否需要进行调整。如果有人找到更好的解决方案,我会将其设为可接受的答案。

我基本上在加载页面视图控制器时将其向下移动 20pt:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let f = view.frame
    view.frame = CGRect(x: 0, y: 20, width: f.size.width, height: f.size.height)
    view.setNeedsLayout()
    view.layoutIfNeeded()
}

转换后,我将页面视图控制器移回其原始位置,同时第二个视图控制器添加状态栏空间。这会导致第二个视图控制器滑到状态栏的正下方,它应该在哪里。没有明显的震动。我在页面视图控制器的委托中使用了它:

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    guard previousViewControllers.count > 0 else { return }
    // if the transition completed and the view controller we transitioned from is the first view controller
    if completed && viewControllers!.index(of: previousViewControllers.first!) == 0 {
        let f = view.frame
        view.frame = CGRect(x: 0, y: 0, width: f.size.width, height: f.size.height)
        view.setNeedsLayout()
        view.layoutIfNeeded()
    }
}

【讨论】: