Domanda

Ho un modello CoreData che contiene livelli che può ancora contenere childLevels.

Io rappresento ogni livello con un elenco di tutte UITableViewController childLevels. Quando un utente tocca una riga una nuova UITableViewController viene inserito nello navigationController. Nessun problema qui.

Come potrei fare per memorizzare la posizione dell'utente all'interno di questa struttura della tabella. C'è una best practice per fare questo? Non ho alcun problema a fare questo se la profondità della struttura è stata conosciuta, ma in qualche modo perplesso come affrontare questo con una profondità indefinita.

Devo memorizzare il NSIndexPath sfruttato dall'utente in un array e scrivere su disco?

È stato utile?

Soluzione 2

Invece di usare i NSIndexPaths filettati dall'utente sono andato con le NSManagedObjects di fondo che è molto più sicuro (nel numero del caso o l'ordinamento degli oggetti cambia) e più veloce (perché non ho bisogno di tutta la fetchRequest e o vista).

I sottoclasse l'UINavigationController e ha fatto il seguente.

Quando spingendo una nuova TableViewController per un livello (memorizzato in parentLevel) aggiungo questo per una matrice in UserDefaults:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
   [super pushViewController:viewController animated:animated];

   if([viewController isKindOfClass:[LevelTableViewController class]]){
       NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
       NSManagedObject *obj = [(LevelTableViewController*)viewController parentLevel];

       if(obj!=nil){
         [array addObject:[[obj objectID].URIRepresentation absoluteString]];
       } 

       [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:array] objectForKey:LevelTablesPersistentKey];

   }
}

Quando ho pop un viewController ho semplicemente rimuovere l'ultima voce da tale matrice:

- (UIViewController *) popViewControllerAnimated:(BOOL)animated{
  UIViewController *vc = [super popViewControllerAnimated:animated];
  // remove last object
  if([vc isKindOfClass:[LevelTableViewController class]]){
     NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
     [array removeLastObject];
     [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:array] objectForKey:LevelTablesPersistentKey];
  }

  return vc;
}

posso quindi utilizzare questo array durante l'inizializzazione del navigationController quando l'applicazione è successivo ha iniziato a ricostruire l'albero:

- (LevelNavigationController*) initWithRootViewController:(LevelTableViewController*)vc {
if(self = [super initWithRootViewController:vc]){
    // Recreate structure from UserDefaults
    NSArray *array = [NSArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
    [[NSUserDefaults standardUserDefaults] setObject:nil forKey:LevelTablesPersistentKey]; // set the array to nil -> will be rebuild when pushing viewcontrollers onto navigation stack

    NSPersistentStoreCoordinator *persistentStoreCoordinator = ...; // pointer to coordinator 
            NSManagedObjectContext * managedObjectContext = ...; // pointer to your context
    for (NSString *objId in array) {
        NSManagedObjectID *mobjId=[persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:objId]];
        if(mobjId!=nil){

            NSManagedObject *obj = nil;
            NSError **err = nil;
            obj = [managedObjectContext objectWithID:mobjId];

            if(err==nil && obj){
                if([obj.entity.name isEqualToString:@"Level"]){
                    // push level

                    LevelTableViewController *nextLevel = [[LevelTableViewController alloc] initWithStyle:UITableViewStylePlain];
                    nextLevel.parentLevel = (Level*)obj;
                    [self pushViewController:nextLevel animated:NO];
                    [nextLevel release];
                } 
            } 
        }
    }

}

return self;

}

Altri suggerimenti

L'utilizzo di un NSIndexPath per il tuo stato e il salvataggio / ripristino per la persistenza ha senso per me.

Anche il tuo approccio - per usare un NSArray memorizzata come una lista di proprietà (plist) -. Dovrebbe essere abbastanza semplice

Sono quasi pronto per iniziare a fare questo per la mia app e questo è il piano. Ogni volta che un UIViewController carica una nuova vista si creerà un valore nei NSUserDefaults che dà informazioni su tale nuova visione (dove è stato aperto da, quali sono i dati che è popolato con, ecc). Quando la visualizzazione secondaria restituisce il controller della vista cancella questo valore. Quando l'UIViewController ha è di carico iniziale controlla le impostazioni predefinite per vedere se in precedenza memorizzato un valore, in caso affermativo, ci vuole l'azione appropriata per ricaricare quella visualizzazione secondaria. Il processo continua lungo la catena di navigazione.

Il motivo per cui ho fatto questo, invece di un NSIndexPath è perché, oltre alla gerarchia vista principale, ho un po 'di vista ausiliari (aggiungere, rimuovere, modificare, ecc). Non solo ho bisogno di registrare l'apertura di questi punti di vista che esistono al di fuori della navigazione principale, ma avranno un sacco di dettagli statali di cui hanno bisogno per salvare troppo (opzioni selezionate, il testo parzialmente inserito, ecc.)

tornerò qui e downvote questo se si scopre di essere un piano di merda.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top