2011-09-27 12 views
10

Posiblemente un duplicado pero no pude encontrar una pregunta específica en SO, así que aquí está.Mejores prácticas para dibujar alturas de fila de UITableView dinámicas

Tengo curiosidad acerca de cambiar dinámicamente las alturas para todas las filas, por lo general, porque no conoce la longitud de un NSString que se utiliza para una etiqueta.

Sé que debe utilizar este método delegado para cambiar las alturas de las filas:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 

El problema es que este método delegado se llama antes de crear la célula (es decir, antes llamada cellForRowAtIndexPath).

Entonces, lo que he pensado es crear una celda falsa en viewWillAppear y un método que agrega alturas de celda a una matriz que se asigna a la fuente de datos de la vista de tabla (que en mi caso también es una matriz).

viewWillAppear implementa este método importante para obtener la altura:

[NSString sizeWithFont: constrainedToSize: lineBreakMode:]

Luego, en heightForRowAtIndexPath puedo devolver la altura de la celda, así:

//cellHeights is an ivar populated in viewWillAppear 
return [[cellHeights objectAtIndex:indexPath.row] floatValue]; 

Me preguntaba si había una ¿mejor manera de cambiar dinámicamente la altura de la fila?

Me doy cuenta de que esto degradará el rendimiento de una gran cantidad de filas (más de 1000, creo). Pero en mi caso, mis filas nunca se acercarán a ese número. Entonces, el rendimiento alcanzado es insignificante.

¡Gracias de antemano!

Respuesta

8

¡Buena pregunta! De hecho, hice algo similar en algunas de mis aplicaciones.

Puedo pensar en un par de alternativas, pero todas tienen el mismo tema. También puede simplemente usar sizeWithFont: dentro de heightForRowAtIndexPath: y eliminar la matriz. En ese caso, puede tomar un golpe de rendimiento para volver a calcular el tamaño cada vez, si esa operación es costosa.

Usted podría hacer "carga lenta" de la matriz cellHeights interior deheightForRowAtIndexPAth: por lo que podría ser algo como esto:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    if ([cellHeights objectAtIndex:indexPath.row] == nil) { 
     ... calculate height and store it in the array at the correct index... 
    } 

    return [[cellHeights objectAtIndex:indexPath.row] floatValue]; 
} 

La ventaja Pienso en este caso es que sólo se calcule las alturas para celdas que definitivamente van a ser cargadas Si realiza el cálculo en viewWillAppear, ¿supongo que terminará haciéndolo por cada celda, independientemente de si se muestra?

Finalmente, puede poner el tamaño en su propio modelo de datos. Si es, por ejemplo, una matriz de cadenas, puede crear una clase que tenga dos propiedades: una cadena y una propiedad "representationSize". Luego puede recalcular el tamaño de la cadena cada vez que se cambia el valor de la cadena. Entonces, solo habría una matriz, no dos, que se correlaciona con su fuente de datos, llena con una clase de datos que contiene la cadena y el tamaño de visualización de la cadena, y el valor se calculará cuando la cadena cambie, nada para nada cuando aparece la vista

De todos modos, me gustaría escuchar algunos comentarios sobre estos diversos enfoques.

+0

Muy mal. Esperaba más respuestas también. ¡Gracias por tu contribución! –

1

Tengo demasiado problema en mi UITableView, cuando me desplazo a tableview (en iPhone 3gs). Vi muchos retrasos. Así que abro el perfil de tiempo (muy buena herramienta para la optimización) y el problema fue cuando llamé a la función sizeWithFont. La mejor solución para resolver este problema es llamar a sizeWithFont en el constructor.