安全区域和导航栏

Posted

技术标签:

【中文标题】安全区域和导航栏【英文标题】:Safe Area and Navigation Bar 【发布时间】:2018-12-11 18:27:59 【问题描述】:

我正在尝试在 xib 中添加导航栏,但导航栏没有填充到顶部,它在其上方留下了相机凹槽所在的空间。请看下面的截图:

这是我对导航栏的限制:

我还尝试将导航栏的顶部约束设置为 Superview。结果是这样的:

我不敢相信这会这么难。我在这里错过了什么?

【问题讨论】:

【参考方案1】:

您几乎不想将UINavigationBar 直接添加到视图控制器的view,而是希望将视图控制器嵌入UINavigationController。如果您使用故事板,您可以通过选择您的视图控制器,单击编辑器菜单 -> 嵌入 -> 导航控制器来执行此操作。

如果不使用情节提要,您可以创建一个视图控制器,并将其设置为UINavigationController 的根视图控制器。然后显示导航控制器或将该导航控制器嵌入到选项卡控制器或拆分控制器中。

let mySpecialViewController = MySpecialViewController()
let navigationController = UINavigationController(rootViewController: mySpecialViewController)
present(navigationController, animated: true)

上面的代码需要从UIViewController 子类中调用。

如果您是从您的应用委托中执行此操作来设置应用的初始视图控制器,您可以这样做:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    let mySpecialViewController = MySpecialViewController()
    let navigationController = UINavigationController(rootViewController: mySpecialViewController)
    window?.rootViewController = navigationController
    window?.makeKeyAndVisible()
    return true

【讨论】:

如果我不使用情节提要怎么办?我试图远离它们有一个架构上的原因。 如果我添加一个导航控制器并将我的视图控制器安排在里面,我在尝试呈现视图控制器时会出错。即未设置视图属性,或者只能设置一个视图。 我认为这是一个有效的答案,但这是我试图避免的事情。使用该解决方案,我发现 MySpecialViewController 的视图始终从导航栏下方开始,因此我必须添加一些默认填充以将内容向下推送到导航栏下方,我发现这样做容易出错且烦人。 将视图约束到安全区域,这是界面构建器中的默认设置,它将为您处理所有这些插图,并且比尝试调整 UINavigationBar 的高度要容易得多,因为这是在符合UIKit的意图。有关更多信息,您应该观看关于构建 Apps for Every Size and Shape 的 WWDC 会议。 ios 13 开始,而不是在您的 App Delegate 中,现在应该将其放入场景委托的 scene(_:willConnectTo:options:) 实现中。【参考方案2】:
    您应该拥有导航栏的@IBOutlet(如果导航栏是通过编程方式制作的,则为参考)。此外,将栏的顶部约束保持在安全区域。 使您的 ViewController 符合 UINavigationBarDelegate 并设置导航栏的委托 (navigationBar.delegate = self) 实现这个函数并返回.topAttached:
func position(for bar: UIBarPositioning) -> UIBarPosition 
 return .topAttached

【讨论】:

【参考方案3】:

遇到了同样的问题,并且能够找到解决方案。你需要做的是设置委托,实现 positionForBar: 在委托返回 UIBarPositionTopAttached

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar

    return UIBarPositionTopAttached;


【讨论】:

委托方法永远不会被我调用? 很难说为什么没有代码。你是如何设置委托的,你是在代码中做的还是在接口文件中做的?

以上是关于安全区域和导航栏的主要内容,如果未能解决你的问题,请参考以下文章

iOS11中没有状态栏的导航栏与安全区域重叠

定位导航栏顶部的安全区域

添加 TabView 使导航栏无法覆盖 SwiftUI 中的安全区域

在标签栏控制器中嵌入导航控制器会更改视图控制器的安全区域

位置导航栏顶部的安全区域

添加TabView会使导航栏不覆盖SwiftUI的安全区域