I am having problems finding any other information than the docs for how to save the tab order for my UITabBarController, so that the user\'s customization is saved for next
I will explain how to do this programmatically. NOTE: This is using ARC, so you may have to insert retain/release calls as needed.
You use the tag
property of the UITabBarItem
for sorting. For every UIViewController
that you are adding to the UITabBarController
, make sure that each has a unique tag
.
- (id)init
{
self = [super init];
if (self) {
self.tabBarItem.tag = 0;
self.tabBarItem.image = <image>;
self.tabBarItem.title = <title>;
}
return self;
}
Presumably you would just use their default sorting order for their tags, so whatever you have as your original first view controller would be 0, followed by 1, 2, 3, etc.
Set up your UIViewControllers in the AppDelegate's didFinishLaunchingWithOptions
as you normally would, making sure that you are instantiating them in their "default order". As you do so, add them to an instance of a NSMutableArray.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.delegate = self;
NSMutableArray *unsortedControllers = [NSMutableArray array];
UIViewController *viewOne = [[UIViewController alloc] init];
[unsortedControllers addObject:viewOne];
UIViewController *viewTwo = [[UIViewController alloc] init];
[unsortedControllers addObject:viewTwo];
...
After they are all instantiated and added to the array, you will check to see if the user has customized their order by querying NSUserDefaults
. In the defaults, you will store an array of the user's customized tab bar order. This will be an array of NSNumbers (how this is created is explain in the last code snippet). Use these to create a new "sorted" array of view controllers and pass that to the tab bar controller. If they haven't customized the order, the default will return nil and you can simply used the unsorted array.
...
NSArray *tabBarOrder = [[NSUserDefaults standardUserDefaults] arrayForKey:@"tabBarOrder"];
if (tabBarOrder)
{
NSMutableArray *sortedControllers = [NSMutableArray array];
for (NSNumber *sortNumber in tabBarOrder)
{
[sortedControllers addObject:[unsortedControllers objectAtIndex:[sortNumber intValue]]];
}
self.tabBarController.viewControllers = sortedControllers;
} else {
self.tabBarController.viewControllers = unsortedControllers;
}
[self.window setRootViewController:self.tabBarController];
[self.window makeKeyAndVisible];
return YES;
}
To create to customized sort order, use the UITabBarController's delegate method:
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
{
NSMutableArray *tabOrderArray = [[NSMutableArray alloc] init];
for (UIViewController *vc in self.tabBarController.viewControllers)
{
[tabOrderArray addObject:[NSNumber numberWithInt:[[vc tabBarItem] tag]]];
}
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:tabOrderArray] forKey:@"tabBarOrder"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Simplified Rickard Elimää answer even further. "Swift" solution to saving and loading Customized ViewControllers using the delegate function of tabBarController CustomizingViewControllers.
This is how I did it.
class TabBarController: UITabBarController, UITabBarControllerDelegate {
let kOrder = "customOrder"
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
loadCustomizedViews()
}
func loadCustomizedViews(){
let defaults = NSUserDefaults.standardUserDefaults()
// returns 0 if not set, hence having the tabItem's tags starting at 1.
let changed : Bool = defaults.boolForKey(kOrder)
if changed {
var customViewControllers = [UIViewController]()
var tagNumber: Int = 0
for (var i=0; i<self.viewControllers?.count; i++) {
// the tags are between 0-6 and the
// viewControllers in the array are between 0-6
// so we swap them to match the custom order
tagNumber = defaults.integerForKey( String(i) )
//print("TabBar re arrange i = \(i), tagNumber = \(tagNumber), viewControllers.count = \(self.viewControllers?.count) ")
customViewControllers.append(self.viewControllers![tagNumber])
}
self.viewControllers = customViewControllers
}
}
func tabBarController(tabBarController: UITabBarController, didEndCustomizingViewControllers viewControllers: [UIViewController], changed: Bool){
if (changed) {
let defaults = NSUserDefaults.standardUserDefaults()
//print("New tab order:")
for (var i=0; i<viewControllers.count; i++) {
defaults.setInteger(viewControllers[i].tabBarItem.tag, forKey: String(i))
//print("\(i): \(viewControllers[i].tabBarItem.title!) (\(viewControllers[i].tabBarItem.tag))")
}
defaults.setBool(changed, forKey: kOrder)
}
}
}