views:

1132

answers:

1

Setup a new iPhone window based project with a UITabBarController and connect everything up in IB. Using self.tabBarController.selectedIndex = 1; you should be able to switch tabs programmatically. But, it only seems to work in certain circumstances. If you tie it to an IBAction or as the result of the image picker it works great. But, if you call it too quickly it seems to only partially work. The tab gets selected at the view is still the old view.

I tried to put self.tabBarController.selectedIndex = 1; in a switch statement in the viewDidLoad as a method to return to the previously selected tab on launch and it won't work. I then added an NSTimer and tried to do it .01 seconds later and it works fine, so it's obviously a timing/ordering issue.

Any suggestions of when I should be clear to switch tabs?

+1  A: 

Since you started with a window based project, I assume that you're creating your tab bar controller programmatically. The problem here is that viewDidLoad fires as soon as your tab bar controller is initialized (alloc/init). Since your tab bar controller's view controllers property isn't set until after that, you're setting the selected index to 1 when the view controller count is 0. According to the tab bar controller documentation, it will swallow the error and set the selected index back to 0.

The reason that it works with a delay is that the delay is probably long enough to allow your view controllers to be set before setting the selected index. This is dangerous though, because if your view controllers are slow about loading for any reason, you may be setting the selected index before they're ready.

It's irritating that this it works differently than when the tab bar controller is loaded from a nib. If it's loaded from a nib, the view controllers are present before viewDidLoad is invoked.

Anyways, you basically have two options, either of which involves subclassing UITabBarController:

  1. Add your view controllers to the tab bar controller in the tab bars init/initWithNibName method. Then you can set your selected index in viewDidLoad
  2. Override the setViewControllers method, and set your selected index after they've been added.

Haven't tried either of these options, but I'm about to because I ran into the same issue.

Dustin