I have a big app with lots of screens, all arranged in a hierarchy, with a UITabBarController at the top, UINavigationControllers below that, and then UIView Controllers below those, maybe with a modal controller somewhere thrown in for good measure.
The user is allowed to pick a start screen from a list. Once selected, next time the app is started it will start from the specified screen and all the navigation will work as if they had navigated there themselves.
Since I can't subclass UITabBarController and UINavigationController, I can't add any ivars to set any initial navigation information.
So what is the best way get the hierarchy set up and the screen of the correct view controller showing under these conditions, and do it quickly?
You will want to check out NSCoder and save the view hierarchy before exit. This way, to load them up, you just unserialize the view hierarchy and the state should be the same.
Save the index of the tab the user wants to have loaded each time, and then when the app starts set the UITabBarController.selectedIndex property to this index and the then you will need to call viewDidAppear on the UITabBarController.selectedViewController. This should trigger the index to set to be visible.
I do this by saving a bunch of different values as User Defaults. However, my applicationDidFinishLaunching method is a bit messy as I'm using a bunch of conditional statements to push View Controllers onto the stack, decide which tabs are selected, decide if a modal view is shown, etc.
I'm not sure what the problem you're describing is. That is, why not just
Save either the current displayed-view (if there's only one way to get there) or the user's navigation path (if there are multiple routes) on app exit, then
Re-create the view hierarchy as if the user had navigated in your appDidFinishLaunching
...?
So, for example, you might save the class-names of the controllers as they're pushed into the stack then, when the app reloads, create the individual controller classes and push them onto the navigation stack. For tab controllers, you'll need to save the index of which tab was selected at the time.
If your problem/question is more complicated than this, perhaps edit it to explain the specific part where you're getting stuck.
Here's how I did it. Both Methods are in the appDelegate and tabBarController is an instance variable.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
//Remember the users last tab selection
NSInteger tabIndex = self.tabBarController.selectedIndex;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger: tabIndex forKey:@"activeTab"];
if (![userDefaults synchronize])
{
NSLog(@"Error Synchronizing NSUserDefaults");
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
//Set the tabBarController to the last visted tab
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
int activeTab = [(NSNumber*)[userDefaults objectForKey:@"activeTab"] intValue];
self.tabBarController.selectedIndex = activeTab;
}
来源:https://stackoverflow.com/questions/1619478/how-can-i-have-my-iphone-app-start-with-a-specific-screen-showing