保存和恢复标签栏控制器的状态

时间:2009-10-12 05:15:40

标签: iphone objective-c uinavigationcontroller uitabbarcontroller object-state

我有一个应用程序,它有一个带有两个选项卡的UITabBarController,每个选项卡都有自己的导航控制器。现在我想在用户关闭应用程序时存储应用程序的状态,这样当用户重新启动时,应用程序将显示与关闭之前的最后一次相同的位置。
所以,在applicationWillTerminate:我有

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

然后,在applicationDidFinishLaunching中:我有

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

我还对UIImage进行了扩展,使其符合NSCoding。但是,这不起作用,因为状态未被保留。第一个选项卡一直被选中,也不保留任何导航 有人能告诉我什么是错的,或者告诉我如何正确地做到这一点?

2 个答案:

答案 0 :(得分:4)

我认为坚持实际对象太过分了。相反,只需保存selectedIndex属性(使用[NSNumber numberWithInt: tabBar.selectedIndex]),然后将其读回并在启动时设置属性。也许这不能正确回答你的问题,但它可能足以满足你的目标。

答案 1 :(得分:2)

由于Felixyz的想法,我终于想出了如何做到这一点。以下是我存储选项卡所需要做的事情,无论其数据如何。如果说,视图加载了从URL下载的数据,则存储URL而不是整个视图。你必须覆盖

- (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's current view as a subview of the window
    [window addSubview:tabBarController.view];
}