2010-03-02 11 views
25

Sé que esta pregunta se ha hecho antes, y eché un vistazo a la respuesta al this question. Sin embargo, todavía estoy confundido sobre cómo implementar el reordenamiento con una UITableView en un proyecto de Datos centrales. Lo que sé es que necesito tener un atributo "displayOrder" en mi entidad para rastrear el orden de los elementos, y debo enumerar todos los objetos en los resultados obtenidos y establecer su atributo displayOrder.UITableView Núcleo Reordenación de datos

En el código dado en la pregunta que he vinculado, el método delegado de vista de tabla llama a un método como este [self FF_fetchResults];, y no se proporciona el código para ese método, por lo que es difícil decir exactamente qué es.

¿Hay algún código de muestra que así lo demuestre? Eso sería más simple de ver que compartir grandes cantidades de código.

Gracias

+0

¿Has probado el código relacionado? Si está utilizando un controlador de resultados obtenido, es posible que no necesite hacer nada. Ese método simplemente está recuperando los objetos nuevamente (ahora que el género ha cambiado). – gerry3

+0

Gracias, lo intentaré. ¿Es necesario volver a buscar los objetos una vez que la orden ha cambiado? – indragie

+0

No debería necesitarlo si está usando un controlador de resultados obtenido (y tiene un código de placa de caldera para actualizar la vista de tabla cuando cambia el controlador de resultados obtenidos). – gerry3

Respuesta

56

no estoy seguro de qué parte está teniendo problemas con (basado en los comentarios) ... pero aquí es mi sugerencia. DisplayOrder es simplemente un atributo simple en una clase NSManagedObject. Si puede guardar un objeto administrado, entonces podrá finalizar esta función. Vamos a tomar una primera NSManagedObject simple:

@interface RowObj : NSManagedObject 
{ 
} 

@property (nonatomic, retain) NSString *rowDescription; 
@property (nonatomic, retain) NSNumber *displayOrder; 

A continuación, tenemos que tener una copia local de los datos que se muestran en el tableview. He leído los comentarios que ha hecho y no estoy seguro de si está usando el Controlador de resultados recuperados o no. Mi sugerencia sería comenzar de manera simple y simplemente usar un TableViewcontroller normal donde actualices los datos de la fila cada vez que un usuario cambie el orden de visualización ... luego guarda la orden cuando el usuario termine de editar.

La interfaz para esta tableviewcontoller se vería así:

@interface MyTableViewController : UITableViewController { 
    NSMutableArray *myTableViewData; 
} 

@property(nonatomic,retain) NSMutableArray *myTableViewData; 

@end 

A continuación, tenemos que cargar los datos de la tabla general del método viewWillAppear:

- (void)viewWillAppear:(BOOL)animated { 
    myTableViewData = [helper getRowObjects]; // insert method call here to get the data 
    self.navigationItem.leftBarButtonItem = [self editButtonItem]; 
} 

Hay 2 cosas que suceden aquí ... (Explicaré el editButtonItem más adelante), el primero es que necesitamos obtener nuestros datos de CoreData. Cuando tengo que hacer esto, tengo algún tipo de ayuda (llámalo como quieras) el objeto hace el trabajo. Un método hallazgo típico sería el siguiente:

- (NSMutableArray*) getRowObjects{ 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"RowObj" inManagedObjectContext:[self managedObjectContext]]; 
    [request setEntity:entity]; 

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    [request setSortDescriptors:sortDescriptors]; 
    [sortDescriptors release]; 
    [sortDescriptor release]; 

    NSError *error; 
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; 
    if (mutableFetchResults == nil) { 
     // Handle the error. 
    } 
    [request release]; 
    return mutableFetchResults; 
} 

Ahora que ya tiene sus datos, ahora se puede esperar a que el usuario pueda editar la tabla. Aquí es donde entra en juego el [self editButtonItem]. Esta es una característica incorporada que devuelve un elemento de botón de barra que alterna su título y estado asociado entre Editar y Listo. Cuando el usuario pulse ese botón, invocará el método setEditing: animado:

Para actualizar el orden de visualización, debe anular el método setEditing en la clase UITableViewController. Debe ser algo como esto:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated { 
    [super setEditing:editing animated:animated]; 
    [myTableView setEditing:editing animated:animated]; 
    if(!editing) { 
     int i = 0; 
     for(RowObj *row in myTableViewData) { 
      row.displayOrder = [NSNumber numberWithInt:i++]; 
     } 
     [helper saveManagedObjectContext]; // basically calls [managedObjectContext save:&error]; 
    } 
} 

No tenemos que hacer nada cuando el usuario está en el modo de edición ... sólo queremos salvar una vez que se ha pulsado el botón "Done". Cuando un usuario arrastra una fila de la tabla puede actualizar su orden de presentación reemplazando los métodos canMoveRowAtIndexPath y moveRowAtIndexPath:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 
    return true; 
} 

(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { 

    RowObj *row = [myTableViewData objectAtIndex:sourceIndexPath.row]; 
    [myTableViewData removeObjectAtIndex:sourceIndexPath.row]; 
    [myTableViewData insertObject:row atIndex:destinationIndexPath.row]; 
} 

Una vez más, la razón por la que no actualiza el valor displayorder aquí se debe a que el usuario se encuentra todavía en modo de edición...no sabemos si el usuario ha terminado de editar E incluso podrían cancelar lo que han hecho al no presionar el botón "Listo".

EDITAR

Si desea eliminar una fila que necesita para anular tableView: commitEditingStyle: forRowAtIndexPath y hacer algo como esto:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the managed object at the given index path. 
     RowObj *row = [myTableViewData objectAtIndex:indexPath.row]; 
     [helper deleteRow:row]; 

     // Update the array and table view. 
     [myTableViewData removeObjectAtIndex:indexPath.row]; 
     [myTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; 
    } 
} 
+0

Gracias por la respuesta detallada, voy a probar esto. – indragie

+0

Claro, avíseme si tiene algún problema ... esto es básicamente palabra-4-palabra de una implementación en funcionamiento de una de mis aplicaciones, por lo que debería ayudarlo a hacerlo. –

+0

¿Qué tal eliminar filas? ¿Hay algo especial que deba hacerse allí para trabajar con esto? – indragie

Cuestiones relacionadas