3
votes

I have a problem on UINavigationController when pushing view controllers in succession.

For information, I use XCode 7.0, build targeting iOS 8, and the app running on Simulator 9.0.

Here's the view when user manually tap the tableview's cell:

User manually push the controller by tapping on tableview's cell

As shown on the above screenshots, the navigation's and back button's title were rendered normally.

But when I did this programmatically, like this (stack is array of UIViewController):

for controller in stack {
    self.mainNavController.pushViewController(controller, animated: false)
}

or using delay on 0.0 second like this:

for controller in stack {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64((0.0 * Float(NSEC_PER_SEC)))), dispatch_get_main_queue(), {
        self.mainNavController.pushViewController(controller, animated: false)
    })
}

It will show the final result like this (left is w/o delay, right is w/ delay):

enter image description here

Notice the missing navigation title on the left screenshot (w/o delay) and missing back button title on the right screenshot (w/ delay).

This issue has confuse me for days. Any idea of why this is happening? Does anyone know how to fix this? Or at least, work around this issue?

Thanks in advance.

2
can you share the code where you init and add the bar button item?Yannis P.
Did you find a fix for this ? Still going iOS 13.3Petar
Nope. Still didn't find a fix. Just a work around. In the end, I override the back button with my own bar button item, similar to the accepted answer below.Firanto
Actually thinking more about this I believe this could be expected behaviour. If you open your second view controller manually you will have already initialized and shown on screen your first view controller and so its navigation would have been set. Then when the second vc is pushed, the navigation controller will use the first vc's navigation item to show the back button. If you do it programatically though, the first vc is not initialized and there is no navigation item for the nav controller to get the back title from.Petar
Also you shouldn't be pushing view controllers with a loop given there is a UINavigationController function setViewControllers:animatedPetar

2 Answers

1
votes

This is what I have done in the past. You might find it helpful:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let myBackButton = UIBarButtonItem()
    myBackButton.title = "This is my back button"
    navigationItem.backBarButtonItem = myBackButton
}
1
votes

This is happening because the intermediate view controllers are not being told to load so it isn't able to load things properly like the correct messaging for the back button. For any intermediate viewControllers, call loadViewIfNeeded() and then the upper view controllers can get all the required info from them.