3

J'ai une application qui a un UITabBarController avec deux onglets, chacun ayant son propre contrôleur de navigation. Maintenant je veux stocker l'état de l'application quand l'utilisateur le ferme, ainsi quand l'utilisateur relauches l'application montrera le même endroit que la dernière fois avant qu'il ait été fermé.
Ainsi, applicationWillTerminate: jeenregistrer et restaurer l'état d'un contrôleur de barre d'onglets

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

Puis, en applicationDidFinishLaunching: je

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

J'ai aussi une extension UIImage pour le rendre conforme à NSCoding. Cependant, cela ne fonctionne pas, car l'état n'est pas conservé. Le premier onglet est sélectionné tout le temps, et aucune navigation n'est conservée non plus.
Quelqu'un peut-il me dire ce qui ne va pas, ou me montrer comment le faire correctement?

Répondre

2

J'ai trouvé comment le faire finalement, grâce à l'idée de Felixyz. Voici ce que je dois faire pour stocker des onglets, indépendamment de leurs données. Si, par exemple, une vue est chargée avec des données téléchargées à partir d'une URL, stockez l'URL au lieu de l'ensemble de la vue. Vous devrez passer outre

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

dans votre sous-classe UIViewController pour dire au contrôleur de vue de sauvegarder les données appropriées avant l'arrêt de l'application.
maintenant dans votre délégué de l'application enregistrer les données avant quiting

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

Et puis, quand relançant

- (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

Je pense qu'il est exagéré de persister les objets réels. Au lieu de cela, enregistrez simplement la propriété selectedIndex (utilisez [NSNumber numberWithInt: tabBar.selectedIndex]), puis relisez-la et définissez la propriété au lancement. Peut-être que cela ne répond pas correctement à votre question, mais cela pourrait suffire à ce que vous essayez d'accomplir.

+0

fait c'est ce que je pense maintenant, mais les tables ont des contenus dynamiques, donc je ne peux pas il suffit de stocker l'index :( peut-être l'url fera l'affaire – phunehehe

+0

Quelles tables? Si vous utilisez UITableViews, il est également beaucoup plus logique de persister les ** données ** plutôt que les vues elles-mêmes. – Felixyz

+0

les données elles-mêmes est dynamique , donc ne peut pas stocker que de toute façon merci ve ry beaucoup pour me donner l'idée je mets aussi mon code ci-dessous – phunehehe

Questions connexes