You're right. The Storyboard layout is inconsistent and confusing in the case of ViewControllers in the NavigationController stack. The first one offers direct access to the NavigationItem but later ones don't. I suppose that is because there is only one NavigationItem and it needs to be updated dynamically as the ViewControllers are pushed and popped.
The way to deal with this is to do it in code. When a ViewController is pushed, its title
property is used to set the title on the navigation bar. So, in each of your ViewControllers that are in a NavigationController's stack, set its title
in viewDidLoad
:
self.title = "titleForThisVC"
For the rightBarButton
, you add it programmatically as well. If this is your @IBAction
for the button:
@objc func handleRightBarButton() {
print("right button")
}
then you'd add the button like this (again in viewDidLoad
):
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Foo", style: .plain,
target: self, action: #selector(handleRightBarButton))
One last gotcha for UITabBarController
s
If your NavigationControllers are the children of a UITabBarController
, then the title that is used in the tab bar will pick up the title from the first ViewController in the stack as set by the code, but only after that tab has first been accessed. To get around this, the title
property should also be set for the top ViewControllers in the Attributes Inspector in Interface Builder