Saving and restoring the status of the tab bar controller

I have an application with a UITabBarController with two tabs, each of which has its own navigation controller. Now I want to save the state of the application when the user closes it, so that when the user uses the application, the same place will be displayed as the last time before it was closed.
So, in applicationWillTerminate: I have

[NSKeyedArchiver archiveRootObject:tabBarController toFile:@"lastVisitedTab"];

Then in applicationDidFinishLaunching: I have

UITabBarController *last= (UITabBarController *)[NSKeyedUnarchiver unarchiveObjectWithFile:@"lastVisitedTab"];
if (last)
    tabBarController = [last retain];

I also have an extension for UIImage to match NSCoding. However, this does not work because the state is not saved. The first tab is selected all the time, and no navigation is saved.
Can someone tell me what is wrong or show me how to do it right?

+3
source share
2 answers

I figured out how to do this, finally thanks to Felixyz . Below is what I need to do to store tabs, regardless of their data. If, say, data loaded from a URL is loaded in a view, save the URL instead of the entire view. You will have to redefine

- (void)encodeWithCoder:(NSCoder *)encoder
- (id)initWithCoder:(NSCoder *)decoder

UIViewController, , .
,

- (void)applicationWillTerminate:(UIApplication *)application
    // data buffer for archiving
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    // the index of selected tab
    [archiver encodeInt:tabBarController.selectedIndex forKey:@"TAB_INDEX"];
    // array of keys for each navigation controller, here I have 3 navigation controllers
    NSArray *keys = [NSArray arrayWithObjects:
                     @"NAVIGATION_CONTROLLER_1",
                     @"NAVIGATION_CONTROLLER_2",
                     @"NAVIGATION_CONTROLLER_3", nil];
    for (int i = 0; i < keys.count; i++) {
        UINavigationController *controller = [tabBarController.viewControllers objectAtIndex:i];
        NSMutableArray *subControllers = [NSMutableArray arrayWithArray:controller.viewControllers];
        // the first view controller would already be on the view controller stack and should be removed
        [subControllers removeObjectAtIndex:0];
        // for each of the navigation controllers save its view controllers, except for the first one (root)
        [archiver encodeObject:subControllers forKey:[keys objectAtIndex:i]];
    }
    [archiver finishEncoding];
    // write that out to file
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [data writeToFile:[documentsDirectory stringByAppendingPathComponent:@"ARCHIVE_PATH"] atomically:YES];
}

,

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    // set up the tabs
    tabBarController = [[UITabBarController alloc] init];
    tabBarController.viewControllers = [NSArray arrayWithObjects:
                                        [[[UINavigationController alloc] initWithRootViewController:rootViewController1] autorelease],
                                        [[[UINavigationController alloc] initWithRootViewController:rootViewController2] autorelease],
                                        [[[UINavigationController alloc] initWithRootViewController:rootViewController3] autorelease], nil];
    // look for saved data, if any
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSData *archive = [NSData dataWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:@"ARCHIVE_PATH"]];
    // if no data found, skip this step
    if (archive) {
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:archive];
        // set the tab
        tabBarController.selectedIndex = [unarchiver decodeIntForKey:@"TAB_INDEX"];
        NSArray *keys = [NSArray arrayWithObjects:
                         @"NAVIGATION_CONTROLLER_1",
                         @"NAVIGATION_CONTROLLER_2",
                         @"NAVIGATION_CONTROLLER_3", nil];
        // push view controllers up the stack
        for (int i = 0; i < keys.count; i++) {
            NSArray *controllers = [unarchiver decodeObjectForKey:[keys objectAtIndex:i]];
            for (UIViewController *controller in controllers) {
                [((UINavigationController *)[tabBarController.viewControllers objectAtIndex:i]) pushViewController:controller animated:NO];
            }
        }
    }
    // Add the tab bar controller current view as a subview of the window
    [window addSubview:tabBarController.view];
}
+2

, , . selectedIndex ( [NSNumber numberWithInt: tabBar.selectedIndex]), . , , , .

+4

Source: https://habr.com/ru/post/1719860/


All Articles