2009-01-28 8 views

Respuesta

14

Aquí hacemos nuestro trabajo pesado.

- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
     toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row); 
    // fetch the object at the row being moved 
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

    // remove the original from the data structure 
    [rows removeObjectAtIndex:fromIndexPath.row]; 

    // insert the object at the target row 
    [rows insertObject:r atIndex:toIndexPath.row]; 
    NSLog(@"result of move :\n%@", [self rows]); 
} 

Dado que este es un ejemplo básico, hagamos que todas las filas sean movibles.

- (BOOL)tableView:(UITableView *)tableView 
canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 
    return YES; 
} 
+0

Cuando removeObjectAtIndex se llama, será que reducir el número de referencia de dicho objeto (y tal vez hacer que se cancela la asignación)? Creo que exchangeObjectAtIndex: withObjectAtIndex: (como lo sugiere @dreamlax) es más seguro. –

+0

Por cierto, si está respondiendo su propia pregunta, creo que es una buena forma convertirla en una wiki. –

+0

@KristopherJohnson 'exchangeObjectAtIndex: withObjectAtIndex:' no es adecuado en este caso. Tiene una semántica diferente de las requeridas por 'tableView: moveRowAtIndexPath: toIndexPath:'. – Benjohn

0

NSMutableArray tiene un método llamado exchangeObjectAtIndex:withObjectAtIndex:.

+3

He intentado esto, pero el comportamiento es diferente.La tabla no intercambia las filas, elimina una fila y luego la inserta en una ubicación diferente. Si utilizo este método, la mesa y la tienda de respaldo se salen de sincronía con cada movimiento. –

11

Ninguno de los anteriores funcionará. En el código publicado originalmente, la tabla se bloqueará porque elimina los datos que aún estarán en uso, e incluso después de que se corrigió, la matriz no tendría los datos correctos debido a la forma en que la tabla hace una 'reorganización'.

exchangeObjectAtIndex: withObjectAtIndex: no funcionará para la reordenación de un conjunto de acuerdo con la forma de un tableview implementa su propia reordenación

¿Por qué? Porque cuando el usuario selecciona una celda de tabla para reorganizarla, esa celda NO se intercambia con la celda a la que la están moviendo. La celda que seleccionaron se inserta en el nuevo índice de fila y luego se elimina la celda original. Al menos así es como le parece al usuario.

Solución: Debido a la forma en que la mesa de trabajo implementa una reorganización, debemos realizar una comprobación para asegurarnos de agregar y quitar la fila correcta. Este código que preparé es simple y funciona perfecto para mí.

Utilizando los datos de los códigos escritos originales como ejemplo:


- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
     toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row); 
    // fetch the object at the row being moved 
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

     // checks to make sure we add and remove the right rows 
    if (fromIndexPath.row > toIndexPath.row) { 

     // insert the object at the target row 
     [rows insertObject:r atIndex:toIndexPath.row]; 

     // remove the original from the data structure 
     [rows removeObjectAtIndex:(fromIndexPath.row + 1)]; 
    } 
    else if (fromIndexPath.row < toIndexPath.row) { 

     // insert the object at the target row 
     [rows insertObject:r atIndex:(toIndexPath.row + 1)]; 

     // remove the original from the data structure 
     [rows removeObjectAtIndex:(fromIndexPath.row)]; 

    } 

} 

Si se toma unos minutos y echar un vistazo a lo que ocurre con un tableview durante una rearrange se entiende por qué le sumamos de donde el 1 nos hizo.

Soy bastante nuevo en xcode, así que sé que es probable que haya una manera más fácil de hacerlo, o el código puede simplificarse ... Estoy intentando ayudar donde puedo porque me ha costado algunos horas para resolver esto. Espero que esto le ahorre a alguien algo de tiempo!

+1

Esta es la respuesta correcta para la combinación de TableView y NSMutableArray – wayneh

+1

Thanx Wiz. Tu código funciona perfectamente y también tiene sentido. – Ali

5

De acuerdo con la documentación de Apple, y mi propia experiencia, este es un código simple que funciona bastante bien:

NSObject *tempObj = [[self.rows objectAtIndex:fromIndexPath.row] retain]; 
[self.rows removeObjectAtIndex:fromIndexPath.row]; 
[self.rows insertObject:tempObj atIndex:toIndexPath.row]; 
[tempObj release]; 
+0

Buena respuesta. Tu es el más correcto de todos. ¡Gracias hombre! – GeneCode

0

Encontrado esta discusión después de romperse la cabeza contra una implementación sencilla solución ... Michael es el Berding Lo mejor para mí, la forma de Apple, solo recuerda quitar y retener cuando uses ARC. Por lo tanto, una solución más concisa

NSObject *tempObj = [self.rows objectAtIndex:fromIndexPath.row]; 
[self.rows removeObjectAtIndex:fromIndexPath.row]; 
[self.rows insertObject:tempObj atIndex:toIndexPath.row]; 
Cuestiones relacionadas