3

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

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

Тогда в applicationDidFinishLaunching: У меня есть

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

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

ответ

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]; 
} 
4

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

+0

на самом деле это то, что я имею в виду сейчас, но таблицы имеют динамическое содержимое, так что я не могу просто сохраните индекс :( Возможно, URL-адрес будет делать трюк – phunehehe

+0

Какие таблицы? Если вы используете UITableViews, также имеет смысл более точно сохранить ** данные **, а не сами представления. – Felixyz

+0

сами данные являются динамическими , так что не могу сохранить это в любом случае спасибо вам Очень много для того, чтобы дать мне идею Я также поставил свой код ниже – phunehehe

Смежные вопросы