Can you push a UITabBarController inside an UINavigationController

Viewed 7067

Is it not possible to push a UITabBarController inside a UINavigationController? I read back in older versions of iOS but is that still the case now?

5 Answers

I found a case in which the UITabBarController inside UINavigationController does not work as you expect. Code to reproduce the error:

ViewController.swift

class ViewController: UIViewController {

   override func viewDidLoad() {
      super.viewDidLoad()
      navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(someSelector))
   }

}

SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

   var window: UIWindow?


   func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
      guard let windowScene = (scene as? UIWindowScene) else { return }

      let window = UIWindow(windowScene: windowScene)
      window.rootViewController = createRootViewController()
      window.makeKeyAndVisible()
      self.window = window
   }

   fileprivate func createRootViewController() -> UIViewController {
      let viewController = ViewController()
      let tabBarController = UITabBarController()
      tabBarController.viewControllers = [
         viewController
      ]
      let navigationController = UINavigationController()
      navigationController.pushViewController(tabBarController, animated: false)
      return navigationController
   }

I expect an "add" button to appear in the upper right corner. But in the end, the button is not there. However, if you rewrite the method code createRootViewController to the following:

let viewController = ViewController()
let tabBarController = UITabBarController()
tabBarController.viewControllers = [
   UINavigationController(rootViewController: viewController)
]
return tabBarController

then the "add" button appears.

Therefore, if you do not want to spend a few hours debugging, it is better to stick to their advice. I do not know why the developers of the SDK did not add an assert there.

Related