2012-01-21 12 views
5

Tengo problemas con el método reloadData de UITableView. Descubrí que solo llama a cellForRowAtIndexPath si se agregan o eliminan nuevas celdas.Forzar UITableView para llamar a cellForRowAtIndexPath: para todas las celdas

Ejemplo: Tengo cinco celdas, cada una contiene cinco cadenas. Si agrego una nueva celda y llamo al reloadData, la tabla se actualiza y la veo. Sin embargo, si voy a una de las cinco celdas, agrego una nueva cadena, luego regreso y llamo al reloadData, no se llama a ninguno de los métodos delegados de la vista de tabla.

Mi pregunta: ¿Es posible obligar a la vista de tabla a volver a cargar completamente los datos en todas sus celdas visibles?

Respuesta

8

Encontré el problema: tenía el código de personalización de mi celda en el bloque if(cell == nil), así que debido a que las células se reciclaban, no se cambiaban. Sacar el código de personalización de ese bloque solucionó el problema.

+0

Has ahorrado mis horas de esfuerzo. ¡Gracias! No habría adivinado este estúpido error :) – Pruthvid

+0

Me alegra que mi solución pueda ayudar a alguien más. –

0

Bueno, la vista de tabla solo llamará al cellForRowAtIndexPath en las celdas visibles, pero si llama al reloadData, hará eso para que ocurra algo más aquí y no estoy seguro de qué se trata.

+0

En este caso, todas las celdas son visibles. Sé que la fuente de datos (en este ejemplo, NSUserDefaults) se está actualizando, por lo que no estoy seguro de por qué solo se están actualizando las nuevas. –

+0

¿Ha rastreado las llamadas a 'cellForRowAtIndexPath' para comprobar que no se está llamando o simplemente no está viendo un cambio visual? Si 'cellForRowAtIndexPath' no se está llamando ... No sé qué está pasando. En ese punto, daría un paso atrás y rastrearía las llamadas a 'numberOfRowsInSection'. En cualquier caso, puedo decir que se debe llamar a 'cellForRowAtIndexPath' _ _debería llamarse a cada celda visible cuando se realiza' reloadData'. – smparkes

+0

Los NSLogs dicen que cuando agrego una nueva fila, todo se actualiza; mi hipótesis inicial fue incorrecta. Cuando se llama a reloadData al regresar a la vista de tabla desde otro controlador de vista, no se llama nada. –

0

Incluso si su tabla vista tiene 50 filas, solo existirán tantas celdas como puedan ser visibles a la vez. Esa es toda la historia detrás del ReuseIdentifier. Entonces forzar 'todas las celdas' no existe. Si aparece una nueva celda, los datos se cargan dinámicamente.

La única forma de cambiar una celda es cambiar los datos entregados por el método dataSource cellForRowAtIndexPath.

+1

Me equivoqué en mi pregunta; Lo he actualizado ahora. –

+0

Y si intenta 'reloadRowsAtIndexPaths: withRowAnimation:' Solo para comprobar ... No dejar que esta sea la solución. – Jodocus

+0

Eso tampoco funciona; no tiene efecto. –

0

No saque su código del bloque if (cell == nil). En cambio, crea un identificador representativo para la celda que estás creando; intente y asegúrese de que todo el contenido de la celda se mencione en el identificador. Por ejemplo, si tiene 3 números que se muestran, asegúrese de tener esos tres números en el identificador de una manera única que solo se refiera a una celda que tenga dicho contenido.

Digamos que tiene tres propiedades NSArray en su clase, array1, array2 y array3 que tienen valores int envueltos dentro de objetos NSNumber. Que desea utilizar esos NSArrays para llenar un UITableView, esto es lo que haría:

- (UITableViewCell *)tableView:(UITableView *)tableView 
        cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSString *identifier = [NSString stringWithFormat:@"%@-%@-%@", 
          [[array1 objectAtIndex:indexPath.row] intValue], 
          [[array2 objectAtIndex:indexPath.row] intValue], 
          [[array3 objectAtIndex:indexPath.row] intValue]]; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 

    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] 
            initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:identifier] autorelease]; 

     //Build your cell here. 
    } 

    return cell; 
} 
1

he encontrado que la recarga secciones vuelve a cargar los datos más fácilmente. Si sólo tiene una sección que puede probar:

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

1

puede probar esta

[tableView reloadData]; 

o

[tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade]; 

poner esto en commitEditingStyle método.

Cuestiones relacionadas