Programmatically add a UINavigationBar that does underlap the status bar

烈酒焚心 提交于 2019-12-09 23:45:44

问题


I am adding a UINavigationBar manually in a View Controllers loadView.

I am using Cartography (https://github.com/robb/Cartography) to layout views with Auto Layout.

self.edgesForExtendedLayout = UIRectEdge.None
        let navBar = UINavigationBar()
        navBar.delegate = self
        view.addSubview(navBar)

        constrain(navBar) { bar in
            bar.top == bar.superview!.top
            bar.centerX == bar.superview!.centerX
            bar.width == bar.superview!.width
        }

Delegate method:

public func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
        return .TopAttached
    }

Yet the result is small bar, not the extended version under the status bar.


回答1:


If you are adding a navigation bar programmatically you need to be aware that edgesForExtendedLayout and any bar positioning API will not be relative to the layout guides of your interface. Since you have now indicated you want to manage this bar, the system can't enforce whether it should be under the status bar or not. What you need to do is configure your constraints such that the bar will always be positioned relative to the top layout guide.

So for starters lets head to your loadView method:

let bar = UINavigationBar()
bar.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(bar)
self.navBar = bar
let topLayoutGuide = self.topLayoutGuide

We now need to make sure that the navigation bar's bottom is positioned relative to the layout guide. So all we do is say that the bottom of the navigation bar = layoutGuides's top + 44. Where 44 is a decent height for a navigation bar. Remember the layout guide can change when you are in a phone call so its important to always use the layout guide and never hardcode the status bar height.

Approach Using Cartography

constrain(navBar) { bar in
    bar.top == bar.superview!.top
    bar.width == bar.superview!.width
    bar.bottom == topLayoutGuide.top + 44
}

Approach Using NSLayoutConstraints

let navBarTopConstraint = NSLayoutConstraint(item: bar, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: 0)
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[bar]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["bar":bar])
let navBarBottomConstraint = NSLayoutConstraint(item: bar, attribute: .Bottom, relatedBy: .Equal, toItem: topLayoutGuide, attribute: .Top, multiplier: 1, constant: 44)
self.view.addConstraints([navBarTopConstraint,navBarBottomConstraint,horizontalConstraints]))

Voila! You now have a custom navigation bar in a couple of lines that responds to the status bar



来源:https://stackoverflow.com/questions/27823401/programmatically-add-a-uinavigationbar-that-does-underlap-the-status-bar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!