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.
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