UINavigationController, and TabBarController programmatically (no storyboards)

坚强是说给别人听的谎言 提交于 2020-12-28 09:29:46

问题


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

回答1:


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



回答2:


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!




回答3:


You may want to try this:

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


来源:https://stackoverflow.com/questions/43961766/uinavigationcontroller-and-tabbarcontroller-programmatically-no-storyboards

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!