¿Se invoca heightForRowAtIndexPath para todas las filas y cuántas filas en una UITableView antes de los problemas de performance?

Pensé que había leído eso para un UITableView que heightForRowAtIndexPath no se heightForRowAtIndexPath en todas las filas, sino solo en las que serán visibles. Sin embargo, esto no es lo que estoy viendo. Estoy viendo cientos de llamadas a heightForRowAtIndexPath por la simple situación de la orientación que se está cambiando del iPhone, por ejemplo.

Por lo tanto, UITableView aquí que para un UITableView con heightForRowAtIndexPath implementado, se heightForRowAtIndexPath (es decir, heightForRowAtIndexPath ) para todas las filas (no solo las visibles) … avíseme si esto no es del todo correcto.

PREGUNTA: Teniendo en count lo anterior, ¿cuántas filas en un UITableView (donde se implementa heightForRowAtIndexPath ) pueden tener antes de que los problemas de performance ocurran típicamente?

¿Hay alguna forma de resolver los problemas de performance? es decir, establezca una altura nominal / estándar para cada fila y no aplique heightForRowAtIndexPath , pero luego configure correctamente cada altura de fila solo cuando se muestre y heightForRowAtIndexPath correctamente aquí … pero ¿en qué método se haría esto?

Eche un vistazo a la sección de discusión en tableView:heightForRowAtIndexPath: documentation

El método permite al delegado especificar filas con diferentes alturas. Si este método se implementa, el valor que devuelve anula el valor especificado para la propiedad rowHeight de UITableView para la fila dada.

Hay implicaciones de performance para usar tableView: heightForRowAtIndexPath: en lugar de la propiedad rowHeight . Cada vez que se muestra una vista de tabla, llama a tableView: heightForRowAtIndexPath: en el delegado para cada una de sus filas, lo que puede generar un problema de performance significativo con vistas de tabla que tienen una gran cantidad de filas (aproximadamente 1000 o más).

Por lo tanto, debe usar la propiedad rowHeight de UITableView. Si necesita diferentes alturas, no tiene suerte porque tiene que usar tableView:heightForRowAtIndexPath:

AFAIK no hay forma de cambiar la altura de la fila en la pantalla.
El tableview tiene que saber el tamaño correcto antes, de lo contrario, habría cambios feos de position todo el time.

Creo que encontré una solución a eso.

En iOS 7 Apple introdujo algunas nuevas properties de tableview. Uno de ellos es el:

 tableView:estimatedHeightForRowAtIndexPath: 

Por lo tanto, si proporciona una altura de fila estimada, por ejemplo, cuando tableView: heightForRowAtIndexPath: se invoca repetidamente antes de que se muestre la tabla, se llama solo para las celdas visibles de la tabla; Para las celdas restantes, se usa la altura estimada.

Aquí está la fuente de esa información: https://books.google.gr/books?id=wLaVBQAAQBAJ&pg=PT521&lpg=PT521&dq=heightforrowatindexpath+only+for+the+visible+cells&source=bl&ots=7tuwaMT5zV&sig=h3q8AaFvoCgcrPu2fQchVkIEjwg&hl=es&sa=X&ved= 0CEMQ6AEwBWoVChMInLK0xbPuxwIVCbUaCh3_nQWG # v = onepage & q = heightforrowatindexpath% 20only% 20for% 20the% 20visible% 20cells & f = false

Una forma de mejorar el performance en tableViews con un gran número de filas y alturas de celdas dinámicas es almacenar en caching la altura de las celdas una vez que se calculan por primera vez.

Un enfoque simplist para lograr esto es mantener un NSMutableDictionary en el que la key es el id del logging en la celda (o cualquier otro identificador que pueda tener), y el valor es un NSNumber con el alto de la fila. Una vez que se calcula por primera vez la altura, guárdela como NSMutableDictionary por la ID de logging. En tableView:heightForRowAtIndexPath y tableView:estimatedHeightForRowAtIndexPath: verifica la altura de caching en el dictionary y la devuelve si la encuentras. Si no se encuentra, calcule la altura y almacene en el caching antes de devolver la altura.

Debería tener cuidado al invalidar el caching para las filas que cambian de altura. Por ejemplo, si tiene un button expandir en una de sus celdas, tendrá que eliminar la altura de esa celda del caching una vez que se pulsa el button expandir. Se invoca el método delegado para la altura.

Es posible que aún tenga un golpe de performance si intenta mostrar 1000 celdas a la vez cuando la tabla muestra, ya que es probable que llame al método de altura para cada fila. Un trabajo para eso es calentar primero el caching, si es posible en una tarea en segundo plano, antes de mostrar primero las celdas.

¡Dios mío, pasé más de una hora tratando de encontrar la fuente de mi problema de performance!

Finalmente también encontré cientos de llamadas a heightForRowAtIndexPath y una búsqueda me consiguió este hilo. ESO es realmente molesto. El performance baja aquí cuando solo se muestran 250 elementos. Afortunadamente, las celdas que quiero mostrar ahora tienen el mismo tamaño. ¡Pero podría imaginar a alguien que quiera mostrar algunas celdas diferentes para una tablaView con> 200 artículos!

¡ARREGLO ESTA APPLE!

Aclamaciones