Pregunta

I tiene un modelo CoreData que contiene niveles que puede contener de nuevo childLevels.

Yo represento a cada nivel con una lista de todos UITableViewController childLevels. Cuando un usuario toca una fila una nueva UITableViewController se empuja sobre el navigationController. No hay problema aquí.

¿Cómo hago para almacenar la ubicación del usuario dentro de esta estructura de la tabla. ¿Hay una mejor práctica para hacer esto? Tengo ningún problema en hacer esto si se conoce la profundidad de la estructura, pero de alguna manera desconcertado a la forma de abordar esto con una profundidad definida.

¿Debo guardar el NSIndexPath aprovechado por el usuario en una matriz y escribir en el disco?

¿Fue útil?

Solución 2

En lugar de utilizar los NSIndexPaths roscados por el usuario Fui con los NSManagedObjects subyacentes, que es mucho más seguro (en número de caso o la clasificación de los objetos modificar) y más rápido (porque yo no necesito todo el fetchRequest y o vista).

Me subclases la UINavigationController e hice lo siguiente.

Cuando se empuja una nueva TableViewController para un nivel (almacenado en parentLevel) añado esto a una matriz en 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];

   }
}

Cuando hago estallar una viewController Me basta con quitar la última entrada de esa matriz:

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

A continuación, puedo utilizar esta matriz al inicializar el NavigationController cuando la aplicación se inicia la siguiente ocasión para reconstruir el árbol:

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

}

Otros consejos

El uso de un NSIndexPath de su estado y salvar / restaurar por la persistencia tiene sentido para mí.

Además de su enfoque - utilizar un NSArray almacena como una lista de propiedades (plist) -. Debería ser bastante sencillo

Estoy casi listo para empezar a hacer esto por mi propia aplicación y este es el plan. Cada vez que un UIViewController carga un nuevo punto de vista que va a crear un valor en los NSUserDefaults que da información sobre ese nuevo punto de vista (en el que se abrió desde, qué datos se rellena con, etc). Cuando la subvista devuelve el controlador de vista borra este valor. Cuando el UIViewController tiene su carga inicial comprueba los valores por defecto para ver si previamente almacena un valor, si es así, que toma la acción apropiada para recargar que subvista. El proceso continúa hacia abajo la cadena de navegación.

La razón por la que he hecho esto en vez de un NSIndexPath se debe a que, además de la jerarquía de la vista principal, tengo un montón de puntos de vista auxiliares (añadir, eliminar, editar, etc.). No sólo voy a tener que registrar la apertura de estos puntos de vista que existen fuera de la navegación principal, pero tendrán una gran cantidad de detalles del estado que necesitan para salvar también (opciones seleccionadas, texto introducido parcialmente, etc.)

Voy a volver aquí y downvote esto si resulta ser un plan de mierda.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top