I am using Eureka forms. One of my custom selector rows presents another VC (EditorVC
) modally, in the style of formSheet
.
I can do this by presenting a UINavigationController
and have EditorVC
as the root VC. However, that would require me to pass data (namely the row's value when something changes in EditorVC
) between the UINavigationController
and EditorVC
. That's too troublesome for me.
This is why I resorted to programmatically creating a nav bar.
I searched on SO and this is my first try:
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]
When I run the app on an iPhone, the nav bar shows up as expected, but if I change the screen orientation, the nav bar maintains its width and thus does not cover the full width of the screen. On an iPad, the nav bar is too wide. It exceeds the width of the form, so the right bar button item can't be seen. The title is also not centered.
So I tried to add layout constraints to the nav bar:
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])
But apparently it does not change anything. When I run the app, the exact same thing happens.
How can I create a nav bar that can always fit the screen width? This must be possible, right? Because the UINavigationController
somehow did it.
you just need to set translatesAutoresizingMaskIntoConstraints to false and all will be ok. You need this because you add constraints to your view on your own. If you don't do that than you must handle navbar width on your own when phone changes orientation ( viewWillTransition()... ).
Also if this is set to true and you add your own constraints you will probably get some conflicts.
So, do this:
let myNav = UINavigationBar(frame: CGRect.zero)
myNav.translatesAutoresizingMaskIntoConstraints = false
also you don't need to set width of navbar because you use constraints. You just set it CGRect.zero
You can read more about translatesAutoresizingMaskIntoConstraints here