Para un ejemplo simple de usar un NSMutableArray de cadenas llamadas filas, ¿qué tengo que implementar en mi controlador de tabla para mover las filas de tableView y tener los cambios reflejados en mi matriz?¿Qué métodos tengo que implementar para reorganizar las filas de UITableView?
Respuesta
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;
}
NSMutableArray
tiene un método llamado exchangeObjectAtIndex:withObjectAtIndex:
.
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. –
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!
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];
Buena respuesta. Tu es el más correcto de todos. ¡Gracias hombre! – GeneCode
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];
- 1. ¿Cómo hacer que UITableView se pueda reorganizar?
- 2. UITableView que muestra más filas que las especificadas en numberOfRowsInSection:
- 3. cómo borrar todas las filas de UITableView
- 4. WPF multilínea TabControl sin reorganizar filas
- 5. ¿Cómo crear rutas de índice para todas las filas y todas las secciones para uitableview?
- 6. ¿Qué CursorAdapter tengo que usar?
- 7. Tengo problemas para implementar ecuaciones matemáticas en la programación
- 8. seleccionar varias filas en UITableView
- 9. ¿Por qué UITableView llama a los métodos delegados de UIScrollView?
- 10. Cómo crear una barra de herramientas entre las filas UITableView
- 11. La manera más fácil de reorganizar los métodos en Eclipse
- 12. UITableView: cómo mantener fijas las filas de la tabla a medida que el usuario se desplaza
- 13. ¿En qué orden se llaman los métodos de enlace UITableView?
- 14. Eliminar secciones sin filas de UITableView
- 15. métodos de delegado y origen de datos para UITableView
- 16. ¿Cómo reorganizar las columnas de Mysql?
- 17. ¿Por qué tengo que usar finalmente para cerrar recursos?
- 18. Usar filas de inserción en una UITableView
- 19. ¿Por qué tengo que usar $ (esto)?
- 20. filas UITableView cargan de forma asíncrona
- 21. ¿Por qué tengo que usar [ProtoInclude]?
- 22. ¿Por qué tengo que usar close() para cerrar un archivo?
- 23. Agregar filas a la sección UITableView existente
- 24. ¿Por qué tengo que URI.encode incluso los caracteres seguros para las solicitudes Net :: HTTP?
- 25. Forzar UITableView para llamar a cellForRowAtIndexPath: para todas las celdas
- 26. UITableView: ¿qué fila fue seleccionada?
- 27. Programmaticlaly mover filas con animación en UITableView
- 28. Comportamiento correcto para métodos de interfaz que no se pueden implementar
- 29. UITableView borrar y recargar las células
- 30. ¿Qué opciones tengo para automatizar enlaces con NInject
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. –
Por cierto, si está respondiendo su propia pregunta, creo que es una buena forma convertirla en una wiki. –
@KristopherJohnson 'exchangeObjectAtIndex: withObjectAtIndex:' no es adecuado en este caso. Tiene una semántica diferente de las requeridas por 'tableView: moveRowAtIndexPath: toIndexPath:'. – Benjohn