сохранить и восстановить состояние контроллера панели вкладок - PullRequest
3 голосов
/ 12 октября 2009

У меня есть приложение, которое имеет UITabBarController с двумя вкладками, каждая из которых имеет свой собственный контроллер навигации. Теперь я хочу сохранить состояние приложения, когда пользователь закрывает его, чтобы при повторном запуске пользователя приложение показывало то же место, что и в прошлый раз перед его закрытием.
Итак, в приложении WillTerminate: у меня есть

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

Затем в приложении DidFinishLaunching: у меня есть

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

У меня также есть расширение UIImage, чтобы сделать его совместимым с NSCoding. Однако это не работает, так как государство не сохранилось. Первая вкладка постоянно выбирается, и навигация также не сохраняется.
Может кто-нибудь сказать мне, что не так, или показать мне, как это сделать правильно?

Ответы [ 2 ]

4 голосов
/ 13 октября 2009

Я думаю, что излишне сохранять настоящие объекты. Вместо этого просто сохраните свойство selectedIndex (используйте [NSNumber numberWithInt: tabBar.selectedIndex]), а затем прочитайте его обратно и установите свойство при запуске. Возможно, это не дает правильного ответа на ваш вопрос, но может оказаться достаточным для того, чего вы пытаетесь достичь.

2 голосов
/ 15 октября 2009

Я понял, как это сделать, наконец, благодаря идее 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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...