如何以编程方式添加实际适合屏幕的导航栏?

Posted

技术标签:

【中文标题】如何以编程方式添加实际适合屏幕的导航栏?【英文标题】:How can I add a navigation bar programmatically that actually fits the screen? 【发布时间】:2017-05-23 06:11:26 【问题描述】:

我正在使用Eureka forms。我的一个自定义选择器行以 formSheet 的样式以模态方式呈现另一个 VC (EditorVC)。

我可以通过提供UINavigationController 并让EditorVC 作为根VC 来做到这一点。但是,这需要我在UINavigationControllerEditorVC 之间传递数据(即EditorVC 发生变化时的行值)。这对我来说太麻烦了。

这就是我采用编程方式创建导航栏的原因。

我在 SO 上搜索过,这是我的第一次尝试:

myNav = UINavigationBar(frame: CGRect(x: 0, y: 0, width: self.view.width, height: 44))
myNav.barTintColor = #colorLiteral(red: 0.3529411765, green: 0.7333333333, blue: 0.3529411765, alpha: 1)
myNav.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
self.view.addSubview(myNav)
let cancelItem: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancel))
cancelItem.tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
let doneItem: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(done))
doneItem.tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
let navigItem: UINavigationItem = UINavigationItem(title: "Title")
navigItem.rightBarButtonItem = doneItem
navigItem.leftBarButtonItem = cancelItem
myNav.items = [navigItem]

当我在 iPhone 上运行应用程序时,导航栏按预期显示,但如果我更改屏幕方向,导航栏会保持其宽度,因此不会覆盖整个屏幕宽度。在 iPad 上,导航栏太宽。它超过了表单的宽度,所以看不到右边的栏按钮项。标题也不居中。

所以我尝试向导航栏添加布局约束:

let top = NSLayoutConstraint(item: myNav, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 0)
let leading = NSLayoutConstraint(item: myNav, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 0)
let trailing = NSLayoutConstraint(item: myNav, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: 0)
view.addConstraints([top, leading, trailing])

但显然它并没有改变任何东西。当我运行应用程序时,会发生完全相同的事情。

如何创建始终适合屏幕宽度的导航栏?这应该是可能的吧?因为UINavigationController 以某种方式做到了。

【问题讨论】:

查看宽度是否在主线程中更新 【参考方案1】:

您只需将 translatesAutoresizingMaskIntoConstraints 设置为 false 就可以了。您需要这个,因为您自己为视图添加了约束。如果您不这样做,则必须在手机更改方向时自行处理导航栏宽度( viewWillTransition()... )。

此外,如果将其设置为 true 并且您添加自己的约束,您可能会遇到一些冲突。

所以,这样做:

let myNav = UINavigationBar(frame: CGRect.zero)
myNav.translatesAutoresizingMaskIntoConstraints = false

你也不需要设置导航栏的宽度,因为你使用了约束。您只需将其设置为 CGRect.zero

你可以阅读更多关于 translatesAutoresizingMaskIntoConstraints here

【讨论】:

以上是关于如何以编程方式添加实际适合屏幕的导航栏?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式在导航栏正下方添加视图?

如何以编程方式创建标签栏控制器后添加导航界面(Swift)

iOS v10 或更低版本:如何以编程方式在导航栏底部添加 UISearchController

以编程方式将按钮添加到导航栏

Swift iOS以编程方式在导航栏下方设置scrollView约束

如何设置 uitoolbar 的背景类似于我的导航栏