58

Can anyone please tell me how to set the default tab when using storyboards in iOS. I can't seem to figure out how to accomplish this.

Thank you

user1145581
  • 1,017
  • 4
  • 13
  • 18
  • what do you mean by default tab? Are you using tabBarController and trying to select the first tab when your app launches?? – Dinesh Raja Oct 30 '12 at 10:41
  • please make sure your question is descriptive and improve your accepted rate too.. – Dinesh Raja Oct 30 '12 at 10:42
  • I created a Tabbed Application using story boards and I want to set it so that the second tab is selected when the app launches. – user1145581 Oct 30 '12 at 20:54
  • 1
    create a property for your tabBarController in your appdelegate and select the index 1 of your tabbar item in your applicationDidFinishLaunching: method. add like this.[tabBarController.tabBar setSelectedItem:1]; – Dinesh Raja Oct 31 '12 at 04:23

12 Answers12

126

Whilst you can set the initial selected tab programmatically like the other answers, to achieve the same in your storyboard without touching code you would perform the following:

  1. Select the Tab Bar Controller in the Storyboard Interface
  2. Show the Identity Inspector in the Utilities panel
  3. Add a new "User Defined Runtime Attribute"
  4. Set the Key Path to "selectedIndex"
  5. Set the Type to "Number"
  6. Set the Value to the index of the tab you wish to select (a value of 1 would select the second tab for example)
  7. Save the Storyboard, build and run the application

This should be what it looks like when you've achieved the above steps:

Joshua Finch
  • 1,585
  • 2
  • 9
  • 6
  • This still works for me on Xcode 6.3.1, iOS 8.3 - any further details on the issue you're having Jason? – Joshua Finch May 13 '15 at 06:22
  • Likely weirdness on my end in that case; it's a crash at `_NSSetUsingKeyValueSetter`: http://pastie.org/10185899 – friedbunny May 13 '15 at 06:33
  • These instructions worked for me, without the subclass. (iOS8.3/Xcode6.3.1) – maninvan Jun 18 '15 at 06:06
  • 6
    Doesn't work for me neither. Xcode 7.2. Error I get is: Failed to set (selectedIndex) user defined inspected property on (UITabBarController): Could not load NIB in bundle: 'NSBundle – oyalhi Dec 14 '15 at 19:14
  • 13
    Works like a charm, make sure you use it on the UITabBarController not the UITabBar or any nested UIViweController. – kiecodes Dec 18 '15 at 13:34
  • worked great for me, very interesting how that works. – Joseph Astrahan Mar 28 '16 at 02:16
  • 7
    Doesn't work on Xcode 7.3. Error `Failed to set (selectedIndex) user defined inspected property on (UITabBarController): Could not load NIB in bundle: 'NSBundle – Burhanuddin Sunelwala May 09 '16 at 05:05
  • I think this works only if you have a .xib file. It does not have anything to do with Xcode version. – Purnima Naik Aug 05 '19 at 18:39
  • 1
    Be careful doing this because accessing a ViewControllers attribute/view this way will cause a pre-emptive call of viewDidLoad. Just something to keep in mind. Otherwise this is definitely the cleanest way – Cameron Porter Nov 25 '19 at 03:30
  • This simply does NOT WORK. "Failed to set (selectedIndex) user defined inspected property" – dub Sep 22 '20 at 12:35
78

Might seem like overkill for some to subclass UITabBarController, but, I think it provides the cleanest solution.

  1. Create BaseTabBarController.swift
  2. Add an @IBInspectable and set it in viewDidLoad:

    class BaseTabBarController: UITabBarController {
    
        @IBInspectable var defaultIndex: Int = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
            selectedIndex = defaultIndex
        }
    
    }
    
  3. In the storyboard, set you UITabBarController to be your new subclass:

enter image description here

  1. Go to the Attributes Inspector add set the new property Default Index:

enter image description here

  1. ta-da! (:
Aviel Gross
  • 9,770
  • 3
  • 52
  • 62
36
  1. Create a new file subclass of UITabBarController;
  2. Add this at the end of viewDidLoad:

    self.selectedIndex = 1;

  3. Set this new file as the Custom Class in the UITabBarController of your Storyboard.

You're done.

Cesare
  • 9,139
  • 16
  • 78
  • 130
DevonDahon
  • 7,460
  • 6
  • 69
  • 114
24

The following code worked for me:

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
tabBarController.selectedIndex = 2;
Cesare
  • 9,139
  • 16
  • 78
  • 130
Rahul Singh
  • 1,219
  • 3
  • 13
  • 36
  • This code assumes that rootViewController is the tabBarController. Which might not always be true. – oyalhi Dec 14 '15 at 19:22
12

You can use one of these two methods:

tabBar.items = tabBarItems;
tabBar.selectedItem = [tabBarItems objectAtIndex:0];

or a direct method from the object

[tabBar setSelectedItem:myUITabBarItem];

or you can combine them to do this:

tabBar.items = tabBarItems;
[tabBar setSelectedItem:[tabBarItems objectAtIndex:0]];

but i havent tested that method yet, hope this helps!

Trevor Rudolph
  • 1,055
  • 4
  • 18
  • 42
  • 1
    How can I create the outlet property for the tabbar controller?please let me know as I am new to storyboard – Rahul Singh May 02 '13 at 05:41
  • yea, i personaly suck at story boarding, i can send you some code if you want? – Trevor Rudolph May 03 '13 at 04:23
  • 1
    let me try to find the exact code and put it up on pastebin, otherwise ill zip it and out it on my website – Trevor Rudolph May 03 '13 at 04:23
  • This is a great answer to a different question – Bradley Thomas Mar 27 '19 at 18:43
  • 1
    As for Swift 5 (Xcode 10.2) this happens to be no longer allowed: `Directly modifying a tab bar managed by a tab bar controller is not allowed.`. The subclassing solution from @Aviel Gross is still working: `selectedIndex = defaultIndex` – emmics Jul 11 '19 at 05:41
4

in appdelegate find applicationDidBecomeActive function and add this lines

let tabBarController = self.window?.rootViewController as! UITabBarController
tabBarController.selectedIndex = 0 // any index you want
zizutg
  • 1,070
  • 14
  • 20
  • How do you know that the rootViewController is always the tabBarController? – oyalhi Dec 14 '15 at 19:16
  • When we are using the tab bar, by default the tabBarController is the rootViewController. Unless otherwise you changed the rootViewController after initiallization – zizutg Dec 16 '15 at 03:21
  • I did it in 'SceneDelegate' in 'willConnectTo' method, where I'm setting rootViewController, and worked. – Mahdi Moqadasi Oct 23 '21 at 11:16
3

My variant is suitable when you want just change the default selected controller, no more customizing. Just add the follow category:

//  UITabBarController+DefaultPage.h
#import <UIKit/UIKit.h>

@interface UITabBarController(DefaultPage)

@end


//  UITabBarController+DefaultPage.m
#import "UITabBarController+DefaultPage.h"

@implementation UITabBarController(DefaultPage)

- (void)viewDidLoad {
    [super viewDidLoad];

    self.selectedIndex = 1;
}

@end

p.s: I prefer @joshua-finch answer

WINSergey
  • 1,977
  • 27
  • 39
2

In the viewDidLoad() of the TabBarController, set selectedIndex to whatever you want. (0 would be the first, 3 would be the fourth, etc.)

jake
  • 124
  • 1
  • 10
1

You can achieve this through Xcode 8 or later (just tested it and don't know if it's available before this version)

Do the steps as @Joshua Finch said but:

  1. Select the bar item instead of the TabBar
  2. Got to "User Defined Runtime Attribute"
  3. Add new key
  4. Name it "selected"
  5. Set its type to boolean and choose true / or check the checkbox
Sebyddd
  • 4,305
  • 2
  • 39
  • 43
  • "xcode 8 or before": did you really mean "before"? It seems to contradict the following sentence, "dunno if its available before this version". Maybe you meant "8 or greater"? – Fabio says Reinstate Monica Oct 05 '16 at 14:45
0

Building upon Aviel Gross' answer, I just wanted to implement this for a UITabBar, as opposed to a UITabBarController. This can be done as follows:

class BaseTabBar: UITabBar {

    @IBInspectable var defaultIndex: Int = 0 {
        didSet {
            self.selectedItem = self.items?[defaultIndex]
        }
    }
}
ThomasHaz
  • 527
  • 4
  • 16
0

Provided you're navigating to your UITabBarController from e.g. a login screen it might be least pain to set the selection there:

        let tabs = self.storyboard?.instantiateViewController(withIdentifier: "tabs") as! UITabBarController
        tabs.selectedIndex = 1
        self.present(tabs, animated:false)
Anton Duzenko
  • 2,366
  • 1
  • 21
  • 26
0

In InterfaceBuilder, disconnect all the segues, then reconnect them in the order you want them to appear.

MH175
  • 2,234
  • 1
  • 19
  • 35