Search code examples
iosswiftuitabbarcontrolleruitabbaritem

Selected Index on Tab Bar not working on Swift


I want to change the default selected view controller of a UITabBar / UITabBarController via selectedIndex.

I tried other solutions I saw in other threads, like changing it in the AppDelegate or in ViewDidAppear like this:

class MainTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setupTabBar()
    }


    override func viewDidAppear(_ animated: Bool) {
        // this is the attempt to set the selected index that doesn't work 
        self.tabBarController?.selectedIndex = 2
    }

    func setupTabBar(){
        let vc1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "mainvc")
        let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondvc")
        let vc3 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "thirdvc")
        let FirstController = UINavigationController(rootViewController: vc1)
        let SecondController = UINavigationController(rootViewController: vc2)
        let ThirdController = UINavigationController(rootViewController: vc3)

        viewControllers = [FirstController, SecondController, ThirdController]
    }

}

Nothing worked so far, and it always shows the selected index = 0.

I set the tab bar view controller as the initial view controller in the Main storyboard. Should I be doing this in the AppDelegate instead?


Solution

  • You are saying that

    class MainTabBarController: UITabBarController {
    

    so self refers to a UITabBarController, but you are setting the selected index of tabBarController of self:

    self.tabBarController?.selectedIndex = 2
    

    There are no tab bar controllers embedded in self. self itself is a tab bar controller! You can just set self.selectedIndex:

    self.selectedIndex = 2
    

    Also, you should do that in viewDidLoad instead of viewDidAppear, because viewDidAppear can happen many times (every time some modal controller is dismissed for example). viewDidLoad will only be called once.