ios 11 自定义导航栏位于状态栏下方
Posted
技术标签:
【中文标题】ios 11 自定义导航栏位于状态栏下方【英文标题】:ios 11 custom navbar goes under status bar 【发布时间】:2017-09-20 15:49:36 【问题描述】:刚刚下载了 xcode 9,我遇到了这个奇怪的问题,在 ios 11 上,我的自定义导航栏似乎只有一半大小,并且位于状态栏下方,在 ios 10 上工作正常。
这是我的代码
let newNavbar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 64))
let navItem = UINavigationItem()
//create and assign the items
newNavbar.setItems([navItem], animated: false)
view.addSubview(newNavbar)
这是截图,左边是ios11,右边是ios10,
【问题讨论】:
这看起来相关:***.com/questions/46275652/… 【参考方案1】:您的代码总是错误的。您不应该自己设置手动添加的导航栏的高度或将其放置在视图的顶部。您应该将导航栏的顶部固定到状态栏的底部(例如安全区域的顶部)并给它一个委托,以便您可以使用 UIBarPositioningDelegate 机制将其位置设置为.topAttached
,这将导致它可以正确伸展到屏幕顶部。
(但您也应该问自己为什么要手动添加导航栏。通常没有理由不将视图控制器包装在 UINavigationController 中 - 即使您不打算这样做做任何实际的导航——只是为了得到导航栏,以及它的所有自动管理。)
【讨论】:
然后按照我的建议尝试。 您对超级视图的顶部空间约束为零。那不是我说要做的。事实上,这正是我说的不要做的。 该死的,你现在可以正常工作了,谢谢,我真的很感激。 @NevinJethmalani 是的,你一定是。没有什么能阻止模态到导航控制器。如果您需要帮助,请将此作为一个真正的问题提出,以便我可以看到实际问题。谢谢! @ApoorvKhatreja 在 iOS 11 / Xcode 9 中,它将是安全区域布局指南顶部锚点。在此之前,它将是顶部布局指南的底部。【参考方案2】:请参阅ios 11 custom navbar goes under status bar / ios 11 navigation bar overlap status bar 以获得答案
不确定这是否是同一个问题,但我们在升级到 iOS 11 时也遇到了这个问题。
见ios 11 custom navbar goes under status bar
我们手动将导航栏高度设置为 64 并固定到超级视图边缘。符合 UINavigationBarDelegate 协议,实现 UIBarPositioningDelegate 委托方法为我们解决了。
我们换了
navigationBar.autoPinEdgesToSuperviewEdgesExcludingEdge(.bottom)
navigationBar.autoSetDimension(.height, toSize: 64)
与
...
if #available(iOS 11.0, *)
navigationBar.topAnchor.constraint(
equalTo: self.view.safeAreaLayoutGuide.topAnchor
).isActive = true
else
navigationBar.topAnchor.constraint(
equalTo: topLayoutGuide.bottomAnchor
).isActive = true
navigationBar.autoPinEdge(toSuperviewEdge: .left)
navigationBar.autoPinEdge(toSuperviewEdge: .right)
navigationBar.delegate = self
...
public func position(for bar: UIBarPositioning) -> UIBarPosition
return .topAttached
这是对一些自动布局调用使用 purelayout DSL (https://github.com/PureLayout/PureLayout)
请转至https://***.com/users/341994/matt 以获得答案
【讨论】:
【参考方案3】:在将导航栏添加到视图后尝试添加一些自动布局约束
if #available(iOS 11.0, *)
newNavbar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
newNavbar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
newNavbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
newNavbar.heightAnchor.constraint(equalToConstant: 64).isActive = true
您实际上可以在早期版本的 iOS 中使用除第三个约束之外的所有约束,但如果它在早期版本中都有效,您可能不想弄乱它。
使用安全布局区域应该将导航栏保持在状态栏下方。
【讨论】:
我们在尝试设置您提到的新约束时崩溃 @dineshprasanna - 你解决了这个崩溃问题吗?问题是什么?我也遇到崩溃说“他们没有共同的祖先。约束或其锚点是否引用不同视图层次结构中的项目?这是非法的。”【参考方案4】:首先,确保您的导航控制器的“显示导航栏”在情节提要中未选中。
然后,从“对象库”中拖放导航栏。给顶部约束等于 20。
它也可以在“iPhone X 模拟器”中完美运行。
编码愉快!
【讨论】:
【参考方案5】:在 Swift 4.1 中尝试过这个解决方案
let menuBar: UIView =
let mb = UIView()
mb.backgroundColor = .red
mb.translatesAutoresizingMaskIntoConstraints = false
return mb
()
private func setupMenuBar()
view.addSubview(menuBar)
let constraints = [ menuBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
menuBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
menuBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
menuBar.heightAnchor.constraint(equalToConstant: 50)]
NSLayoutConstraint.activate(constraints)
【讨论】:
以上是关于ios 11 自定义导航栏位于状态栏下方的主要内容,如果未能解决你的问题,请参考以下文章