Programmatically add a UINavigationBar that does u

2019-04-15 22:29发布

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条回答
叼着烟拽天下
2楼-- · 2019-04-15 22:41

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

查看更多
登录 后发表回答