I have an iOS app with UITabBarController on a master screen, navigating to a detail screen hiding the UITabBarController with setting hidesB
I was facing the exact same issue, where the app was architectured with one navigation controller per tab. The easiest non-hacky way that I found to fix this, was to place the UITabBarController inside a UINavigationController, and remove the individual UINavigationControllers.
Before:
-> UINavigationController -> UIViewController
-> UINavigationController -> UIViewController
UITabBarController -> UINavigationController -> UIViewController
-> UINavigationController -> UIViewController
-> UINavigationController -> UIViewController
After:
-> UIViewController
-> UIViewController
UINavigationController -> UITabBarController -> UIViewController
-> UIViewController
-> UIViewController
By using the outer UINavigationController, you don't need to hide the UITabBar when pushing a view controller onto the navigation stack.
Caveat:
The only issue I found so far, is that setting the title or right/left bar button items on each UIViewController does not have the same effect. To overcome this issue, I applied the changes via the UITabBarControllerDelegate when the visible UIViewController has changed.
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
guard let topItem = self.navigationController?.navigationBar.topItem else { return }
precondition(self.navigationController == viewController.navigationController, "Navigation controllers do not match. The following changes might result in unexpected behaviour.")
topItem.title = viewController.title
topItem.titleView = viewController.navigationItem.titleView
topItem.leftBarButtonItem = viewController.navigationItem.leftBarButtonItem
topItem.rightBarButtonItem = viewController.navigationItem.rightBarButtonItem
}
Note that I have added a preconditionFailure to catch any case when the navigation architecture has been modified