Search code examples
iosswiftxcodeswift3xcode8

UINavigationController, and TabBarController programmatically (no storyboards)


Currently, my AppDelegate file contains this code to establish the CustomTabBarController as the rootViewController:

window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = CustomTabBarController()

I want my app to always have the CustomTabBarController on the bottom, but I want each tab to have a navigation controller. Here is the code I used to set up my tabBarController:

class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let vc1 = FirstViewController()
let vc2 = SecondViewController()
let vc3 = ThirdViewController()
viewControllers = [vc1, vc2, vc3]
}

Here is the code I used to set up my FirstViewController:

class ProfileViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 2
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: VCCellId, for: indexPath) as! firstVCCell

    return cell
}
}

Solution

  • When combining a UITabBarController and UINavigationControllers, the correct way to set that up is to make the UITabBarController the rootViewController. Each tab of your UITabBarController gets its own UINavigationController. So, if you have 4 tabs, you will create 4 UINavigationControllers.

    See: Adding a Navigation Controller to a Tab Bar Interface


    Update

    Building off of the code you added in your updated question, create a UINavigationController for each of your vc1, vc2, and vc3.

    class CustomTabBarController: UITabBarController {
        override func viewDidLoad() {
            super.viewDidLoad()
            let vc1 = UINavigationController(rootViewController: FirstViewController())
            let vc2 = UINavigationController(rootViewController: SecondViewController())
            let vc3 = UINavigationController(rootViewController: ThirdViewController())
    
            viewControllers = [vc1, vc2, vc3]
        }
    
    }
    

    In each of your ViewControllers, set title to the title you want to be displayed in the navigation bar when that tab is selected:

    class FirstViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            view.backgroundColor = .red
            title = "First"
            self.navigationController?.navigationBar.titleTextAttributes =
                [NSFontAttributeName: UIFont(name: "Chalkduster", size: 27)!,
                 NSForegroundColorAttributeName: UIColor.black]
        }
    }