Search code examples
iosswiftuitabbarcontrolleruistoryboarduitabbaritem

How can I set different UITabBarItems for the same storyboard reference included twice in a UITabBarController?


I have a UITabBarController containing four view controllers. The first two of these are storyboard references to the same external storyboard: "BookTable" in the image below.

tab bar controller with two child VCs

I want to set different tab bar icons for these two items, but I can't work out how. If I don't set the tab bar item properties in the embedded storyboard, then there is no tab bar present in the running app, even if I have configured the tab bar in the controller. See the storyboard and the simulator below:

tab bar controller with specified item simulator screenshot with missing items

If I set the tab bar item properties in the embedded storyboard, then the tab bar item is the same for both:

tab bar controller with duplicate items

If I set the tab bar item properties in code, nothing changes:

class TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tabBar.items![0].title = "Test Item 1"
        tabBar.items![1].title = "Test Item 1"
    }

}

I there a way to do this, or will I have to duplicate my storyboard just to set a different tab bar item?


Solution

  • Unfortunately, Interface Builder does not offer too many possibilities when it comes to view controller reusing in tab bar controllers. You'll have to specify the view controllers of the UITabBarController programmatically:

    class TabBarController: UITabBarController {
        override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
            super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    
            setUp()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            setUp()
        }
    
        func setUp() {
            let storyboard = UIStoryboard(name: [storyboard id], bundle: nil)
    
            let firstBookTableVc = storyboard.instantiateViewController(withIdentifier: "BookTable")
            let secondBookTableVc = storyboard.instantiateViewController(withIdentifier: "BookTable")
    
            //configure the view controllers here...
    
            viewControllers = [firstBookTableVc, secondBookTableVc]
    
            tabBar.items?[0].image = [first tab bar image]
            tabBar.items?[1].image = [second tab bar image]
    
            tabBar.items?[0].title = "first title"
            tabBar.items?[1].title = "second title"
        }
    }