代码之家  ›  专栏  ›  技术社区  ›  phunehehe

保存和还原选项卡栏控制器的状态

  •  3
  • phunehehe  · 技术社区  · 16 年前

    我有一个应用程序,它有一个带有两个选项卡的uitabarcontroller,每个选项卡都有自己的导航控制器。现在,我想在用户关闭应用程序时存储它的状态,这样当用户重新启动应用程序时,它将显示与上次关闭前相同的位置。
    因此,在应用程序中将终止:我已经

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

    然后,在applicationDidFinishLaunching中:我已经

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

    我还扩展了uiimage,使其符合nscoding。但是,这不起作用,因为状态不被保留。第一个选项卡一直处于选中状态,也不保留任何导航。
    有人能告诉我怎么了吗,或者告诉我怎么做才对?

    2 回复  |  直到 16 年前
        1
  •  4
  •   Felixyz    16 年前

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

        2
  •  2
  •   Community Mohan Dere    8 年前

    我终于知道怎么做了,多亏了 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];
    }