views:

6840

answers:

3

In my iPhone app, to restore previously viewed tab, on launch I set the setSelectedIndex: (also tried setSelectedViewController: as per docs but to no avail)

This works on iPhone OS 3.0 - however on OS 2.x the selected index greater than 3 (the first 4 tabs) doesn't switch to the required view. This is documented by Apple here: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITabBarController_Class/Reference/Reference.html#//apple_ref/occ/instp/UITabBarController/selectedViewController

Im wondering if its possible to switch to a view controller under iPhone OS 2.x ? Any help is appreciated.

Btw on my simulator setting index greater than 3 throws an error (for iPhone OS 2.x) - so I have wrapped this in a @try{..} @catch(id ..){ } block - hope this technique helps someone.

A: 

I have this working on version 2.

My code sits here and is working lovely.

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Add the tab bar controller's current view as a subview of the window
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

[application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[window addSubview:tabBarController.view];
// Settings getLastViewIndex is just, 0,1,2,3 depending on what it was last set.
tabBarController.selectedIndex = [Settings getLastViewIndex];
John Ballinger
yes, setting the selectedIndex property does work in iphone os 2.x, however it doesn't work if the index is greater than 3. My iPhone app has over 12 tabs.
Ionic Walrus
A: 

The UITabBarController docs regarding selectedIndex spell it out:

This property nominally represents an index into the array of the viewControllers property. However, if the selected view controller is currently the More navigation controller, this property contains the value NSNotFound. Setting this property changes the selected view controller to the one at the designated index in the viewControllers array. To select the More navigation controller itself, you must change the value of the selectedViewController property instead.

In versions of iPhone OS prior to version 3.0, this property reflects the index of the selected tab bar item only. Attempting to set this value to an index of a view controller that is not visible in the tab bar, but is instead managed by the More navigation controller, has no effect.

If I understand correctly, you need to "change the value of the selectedViewController property" instead, but you'll only get as far as selecting the More nav controller, not a VC within it. From the same docs regarding selectedViewController:

This view controller is the one whose custom view is currently displayed by the tab bar interface. The specified view controller must be in the viewControllers array. Assigning a new view controller to this property changes the currently displayed view and also selects an appropriate tab in the tab bar. Changing the view controller also updates the selectedIndex property accordingly. The default value of this property is nil.

In iPhone OS 3.0 and later, you can use this property to select any of the view controllers in the viewControllers property. This includes view controllers that are managed by the More navigation controller and whose tab bar items are not visible in the tab bar. You can also use it to select the More navigation controller itself, which is available from the moreNavigationController property. Prior to iPhone OS 3.0, you could select only the More navigation controller and the subset of view controllers whose tab bar item was visible. Attempting to set this property to a view controller whose tab bar item was not visible had no effect.

As for a workaround, I wonder if the More nav controller's pushViewController:animated: method would come in handy here? Give each view a unique tag number (which you could associate with an appropriate VC behind the scenes). Save the tag for whichever VC was last active.

At startup-time, select the appropriate view in the tab bar controller. If the view's tag isn't associated with the VCs for the first four tab items, it must be within the More nav controller. Locate the VC, push it onto the More nav controller's stack, then select the More nav controller outright.

I haven't tried this, but it might be worth an experiment! The only potential gotcha (and it could be a biggie) is that you will have to push that VC after the More nav controller is setup, not before.

Joe D'Andrea
+1  A: 

Maybe this will help. What I did was save the index of the tab bar item that was selected. When the app launches I check to see if the number is greater than 3, if it is I set the selected tab bar view controller to be the more navigation controller and then just push the saved index tab bar view controller from the more navigation controller.

if ([[WSFUserDefaults sharedInstance] savedTabBarLocation] > 0) {

      if ([[WSFUserDefaults sharedInstance] savedTabBarLocation] > 3) {
       UIViewController *selectViewController = [tabBarController.viewControllers objectAtIndex:[[WSFUserDefaults sharedInstance] savedTabBarLocation]];
       [tabBarController setSelectedViewController:tabBarController.moreNavigationController];
       [tabBarController.moreNavigationController popToRootViewControllerAnimated:NO];//make sure we're at the top level More
       [tabBarController.moreNavigationController pushViewController:selectViewController animated:NO];
      }
      else {
       [tabBarController setSelectedIndex:[[WSFUserDefaults sharedInstance] savedTabBarLocation]];
      }
     }
This works well. What happens when you set selectedIndex is that the more controller is used instead of the original navigation controller, then dynamically switched back. This code gets the initial set-up donee and ensures that the view controller's navigationController pointer is correct.
Steve Weller
Hmm. It works well with one problem: the Edit button on the More screen has gone.
Steve Weller