[ios] Programmatically switching between tabs within Swift

I need write some code to switch the view to another tab when the iOS app starts (so, for example, the second tab is shown by default rather than the first).

I'm new to Swift, and have worked out the following:

  • The code should probably go in the override func viewDidLoad() function of the ViewController of the first tab.

  • The following code shows the second ViewController, but not with the tab bar at the bottom (vcOptions is the second ViewController tab item:

let vc : AnyObject! = self.storyboard.instantiateViewControllerWithIdentifier("vcOptions")
self.showViewController(vc as UIViewController, sender: vc)

I think the answer may lie in using the UITabbarController.selectedIndex = 1, but not quite sure how to implement this.

This question is related to ios xcode swift uitabbarcontroller viewcontroller

The answer is


If you want to do this from code that you are writing as part of a particular view controller, like in response to a button press or something, you can do this:

@IBAction func pushSearchButton(_ sender: UIButton?) {
    if let tabBarController = self.navigationController?.tabBarController  {
        tabBarController.selectedIndex = 1
    }
}

And you can also add code to handle tab switching using the UITabBarControllerDelegate methods. Using tags on the base view controllers of each tab, you can see where you are and act accordingly: For example

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    
    // if we didn't change tabs, don't do anything
    if tabBarController.selectedViewController?.tabBarItem.tag ==  viewController.tabBarItem.tag {
        return false
    }
    
    if viewController.tabBarItem.tag == 4096 { // some particular tab
        // do stuff appropriate for a transition to this particular tab
    }
    else if viewController.tabBarItem.tag == 2048 { // some other tab
        // do stuff appropriate for a transition to this other tab
    }
}

Just to update, following iOS 13, we now have SceneDelegates. So one might choose to put the desired tab selection in SceneDelegate.swift as follows:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, 
               willConnectTo session: UISceneSession, 
               options connectionOptions: UIScene.ConnectionOptions) {

        guard let _ = (scene as? UIWindowScene) else { return }

        if let tabBarController = self.window!.rootViewController as? UITabBarController {
            tabBarController.selectedIndex = 1
        }

    }

Swift 3

You can add this code to the default view controller (index 0) in your tabBarController:

    override func viewWillAppear(_ animated: Bool) {
        _ = self.tabBarController?.selectedIndex = 1
    }

Upon load, this would automatically move the tab to the second item in the list, but also allow the user to manually go back to that view at any time.


The viewController has to be a child of UITabBarControllerDelegate. So you just need to add the following code on SWIFT 3

self.tabBarController?.selectedIndex = 1

1.Create a new class which supers UITabBarController. E.g:

class xxx: UITabBarController {
override func viewDidLoad() {
        super.viewDidLoad()
}

2.Add the following code to the function viewDidLoad():

self.selectedIndex = 1; //set the tab index you want to show here, start from 0

3.Go to storyboard, and set the Custom Class of your Tab Bar Controller to this new class. (MyVotes1 as the example in the pic)

enter image description here


Swift 5

//MARK:- if you are in UITabBarController 
self.selectedIndex = 1

or

tabBarController?.selectedIndex = 1

To expand on @codester's answer, you don't need to check and then assign, you can do it in one step:

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
    // Override point for customization after application launch.

    if let tabBarController = self.window!.rootViewController as? UITabBarController {
        tabBarController.selectedIndex = 1
    }

    return true
}

In a typical application there is a UITabBarController and it embeds 3 or more UIViewController as its tabs. In such a case if you subclassed a UITabBarController as YourTabBarController then you can set the selected index simply by:

selectedIndex = 1 // Displays 2nd tab. The index starts from 0.

In case you are navigating to YourTabBarController from any other view, then in that view controller's prepare(for segue:) method you can do:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
        if segue.identifier == "SegueToYourTabBarController" {
            if let destVC = segue.destination as? YourTabBarController {
                destVC.selectedIndex = 0
            }
        }

I am using this way of setting tab with Xcode 10 and Swift 4.2.


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to xcode

Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64 iPhone is not available. Please reconnect the device Make a VStack fill the width of the screen in SwiftUI error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65 The iOS Simulator deployment targets is set to 7.0, but the range of supported deployment target version for this platform is 8.0 to 12.1 Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) Xcode 10: A valid provisioning profile for this executable was not found Xcode 10, Command CodeSign failed with a nonzero exit code

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to uitabbarcontroller

Programmatically switching between tabs within Swift What size should TabBar images be? Unbalanced calls to begin/end appearance transitions for <UITabBarController: 0x197870> Switching to a TabBar tab view programmatically? Changing Tint / Background color of UITabBar

Examples related to viewcontroller

Presenting modal in iOS 13 fullscreen Swift programmatically navigate to another view controller/scene Swift: Reload a View Controller How do I create a view controller file after creating a new view controller? presenting ViewController with NavigationViewController swift Programmatically switching between tabs within Swift How to dismiss ViewController in Swift? Swift presentViewController How to Navigate from one View Controller to another using Swift