ios - UINavigationController 在推送时显示状态栏的空间

标签 ios uitableview uinavigationcontroller swift3 xcode8

当我使用 Storyboard Segue 推送到下一个 View 时,它会为状态栏加载一个空间,即使下一个 View 已将 prefersStatusBarHidden 设置为 false

我还尝试通过子类化 UINavigationController 并将 prefersStatusBarHidden 设置为 false ,但 View 仍然为其加载空间。另外,automaticallyAdjustsScrollViewInsets 设置为 false

Push to view

加载的 View 由一个 UIViewController 组成,它有一个 UITableViewUIViewController 的背景颜色(用于测试)设置为橙色, TableView 的背景颜色设置为粉色。这些颜色均未显示。

经过一些测试,在我看来,UINavigationController为其 Root View 添加了一个空格,并在推送动画后删除了该空格。如果我将 UINavigationController 的背景颜色设置为紫色,则会得到以下结果:

Result 2

这表明它推送到的 View 既没有重新渲染,也没有处于正确的 Y 位置。我似乎无法找到这是为什么。

我的UINavigationController包含在UIViewController中,它有一个 View 容器(rootViewController)。 每当请求加载根页面时,都会以编程方式创建导航 Controller 。这是代码:

/// Load a view controller with UINavigationController into the 
/// rootViewController and display it
///
/// - Parameter viewController: The view controller to show
func loadViewControllerPage(_ viewController: UIViewController) {
    let nav = UINavigationController(rootViewController: viewController)

    // No bar, please
    nav.isNavigationBarHidden = true

    // Make the view get in there propperly
    nav.willMove(toParentViewController: self)
    addChildViewController(nav)
    nav.view.willMove(toSuperview: rootViewController)
    nav.view.frame = rootViewController.bounds
    rootViewController.addSubview(nav.view)
    nav.view.didMoveToSuperview()
    nav.didMove(toParentViewController: self)
    rootViewController.bringSubview(toFront: nav.view)

    /* Test if this fixes the statusbar issue
    nav.edgesForExtendedLayout = .all
    nav.automaticallyAdjustsScrollViewInsets = false
    nav.extendedLayoutIncludesOpaqueBars = false
    */

    currentNav = nav

    // Cleanup
    for child in childViewControllers {
        if let c = child as? UINavigationController, c != nav && c.view.isDescendant(of: rootViewController) && c != menuView {
            c.removeFromParentViewController()
            c.view.removeFromSuperview()
        }
    }
}

关于如何解决这个问题有什么建议吗?

最佳答案

概要

  • 不要尝试触发 iOS 消息。以编程方式调用 didMoveToSuperview() 无疑表明设计可能存在缺陷,或者充其量是不必要的复杂
  • 无需使用loadViewControllerPage将 View 推送到导航 Controller 或替换 Root View Controller
  • 无需以编程方式创建导航 Controller 。让 Interface Builder 为您准备资源,并根据需要加载它。
  • 导航 Controller 的重点是处理导航;不要绕过该机制并手动加载 View

请注意,在橙色 View 上可见的状态栏在蓝色 View 上不可见。 See animation.

Animation showing the status bar disappearing


建议

When I push, using storyboard segue, to the next view, it loads a space for the statusbar, even though the next view has set the prefersStatusBarHidden to false.

隐藏状态栏

要隐藏第二个 View Controller 中的状态栏,请将 prefersStatusBarHidden 设置为 true,而不是 false。

override var prefersStatusBarHidden:Bool {
    return true
}

隐藏导航栏

如果您不想显示导航栏,请在导航 Controller 属性检查器中更改导航栏可见性

使用 Storyboard转场

不需要任何代码。如果您确实必须以编程方式使用 segues,请参阅 this StackOverflow answer .

以编程方式创建导航 Controller

不需要走这条路。使用 Storyboard ID 从 Storyboard查找并加载导航 Controller 。

UINavigationController 子类

为什么在 loadViewControllerPage 周围有这么多代码,为什么要子类化 UINavigationController

控制自定义转换

如果您的自定义 UIViewController 加载的对象是动画,请参阅 this StackOverflow post .

Storyboard中的设计过渡

导航 Controller 可见性、状态栏可见性、segues,所有这些都由资源定义,并且生成很少甚至没有代码。

enter image description here

关于ios - UINavigationController 在推送时显示状态栏的空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40761543/

相关文章:

ios - 如何在 UITableView 中设置单元格高度?

ios - Amazon polly 不读取第一个单词/在 iOS Swift 中听不到

ios - 异步加载图片,奇怪的问题

ios - drawRect - 图像滚动性能

ios - Swift 调用 setNavigationBarHidden 但 View 不会移动到顶部

objective-c - 使导航 Controller 在 iOS 6 和 iOS 7 中工作相同

ios - UINavigationController返回多步

ios - 我试图将两个变量传递给方法但得到一个断点 :thread error

用于测试 HTTP 响应代码和时间的 iOS App

iphone - 核心图 - 禁用 y 方向的缩放和滚动,而不是 x