简体   繁体   中英

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
}
}

When combining a UITabBarController and UINavigationController s, 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 ViewController s, 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]
    }
}

I noticed in the comments of the accepted answer that you were wondering where to change the attributes of the navigation bar. If you plan on applying the same customization to each tab you could use the following code within your CustomTabBarController:

class CustomTabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Tab Bar Customisation
        tabBar.barTintColor = .systemPink
        tabBar.tintColor = .systemTeal
        tabBar.unselectedItemTintColor = .systemGray
        tabBar.isTranslucent = false

        viewControllers = [
            createTabBarItem(tabBarTitle: "Tab 1", tabBarImage: "TabBarImg1", viewController: ViewControllerOne()),
            createTabBarItem(tabBarTitle: "Tab 2", tabBarImage: "TabBarImg2", viewController: ViewControllerTwo()),
            createTabBarItem(tabBarTitle: "Tab 3", tabBarImage: "TabBarImg3", viewController: ViewControllerThree()),
            createTabBarItem(tabBarTitle: "Tab 4", tabBarImage: "TabBarImg4", viewController: ViewControllerFour())
        ]
    }

    func createTabBarItem(tabBarTitle: String, tabBarImage: String, viewController: UIViewController) -> UINavigationController {
        let navCont = UINavigationController(rootViewController: viewController)
        navCont.tabBarItem.title = tabBarTitle
        navCont.tabBarItem.image = UIImage(named: tabBarImage)

        // Nav Bar Customisation
        navCont.navigationBar.barTintColor = .systemRed
        navCont.navigationBar.tintColor = .systemBlue
        navCont.navigationBar.isTranslucent = false
        return navCont
    }
}

Personally, I like this approach, because it saves me from repeating code throughout ViewControllers and keeps the tab & nav bar code organized within your custom tab bar class.

If you don't want to use the same tab or nav bar customization throughout the app you can simply customize each one individually how you like within their respective ViewControllers class. However, if every tab is going to have different tab and/or nav attributes Vacawama's answer would most likely be the best approach!

你可能想试试这个:

viewControllers = [vc1, vc2, vc3].map{UINavigationController(rootViewController: $0)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM