Saturday, September 5, 2009

Saving Tabs

I've been so ranty lately that I thought I should take a short break from writing More iPhone 3 Development to put up something technical. This is a relatively beginner-level tutorial, but it's one of those little features we take for granted but really hate when it's not there (at least I do).

I'm talking about saving the selected tab. When you start Apple's Clock application, for example, it always takes you to the tab you were on when you last used it. In most cases, this is a very good idea. There may be cases where a specific tab should have preference, but generally, you should bring the user back where they left off.

If you're using a tab bar controller, it's relatively simple to implement this. In viewDidLoad or applicationDidFinishLaunching:, you need to do something like this:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger whichTab = [defaults integerForKey:kSelectedTabDefaultsKey];
tabBarController.selectedIndex = whichTab;

Then, either when the selection changes, or when the application quits, you have to store off the tab in the preferences so it'll be there next time. I prefer doing it whenever the tab selection changes because then we've captured it, even if there's a crash or phone call, but doing it when the application finishes is fine for most purposes. Here's how you reverse the process:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger whichTab = tabBarController.selectedIndex;
[defaults setInteger:whichTab forKey:kSelectedTabDefaultsKey];

But what if you're just using a UITabBar and not a UITabBarController? That's a touch more difficult because tab bars don't work by indices. It's relatively easy to add the exact same functionality that's on the tab bar controller to the tab bar by using a category, however:

UITabBar-Index.h
#import <Foundation/Foundation.h>

@interface UITabBar(Index)
- (NSUInteger)selectedIndex;
- (void)setSelectedIndex:(NSUInteger)newIndex;
@end



UITabBar-Index.m
#import "UITabBar-Index.h"

@implementation UITabBar(Index)
- (NSUInteger)selectedIndex {
return [self.items indexOfObject:self.selectedItem];
}

- (void)setSelectedIndex:(NSUInteger)newIndex {
self.selectedItem = [self.items objectAtIndex:newIndex];
}

@end


Once you have that, you can import this category and use the exact same code from above on the tab bar rather than the tab bar controller.

Here's an example project. It includes a functioning tab bar application that saves the tab position, and also contains the category above.

No comments:

Post a Comment