Comprender UITableView dequeueReusableCellWithIdentifier: devuelve la celda incluso en la primera llamada

Tengo problemas para entender cómo funciona esto. He leído muchos hilos sobre esto, como UITableView dequeueReusableCellWithIdentifier Theory y cómo dequeueReusableCellWithIdentifier: ¿funcionan? .

Sin embargo, mi UITableView elimina con éxito una celda cada vez (nunca es nula), incluso cuando se carga por primera vez. Tenía la printing de que las células similares deberían usar el mismo identificador, por lo que solo tienes que cambiar lo que sea necesario.

Porque

if (!cell) { NSLog(@"New cell"); cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier]; } 

Nunca se llama, no estoy seguro de cómo se supone que debo manejar las celdas en la misma tabla con diferentes styles, porque el estilo solo se puede configurar en el inicializador.

También intenté usar diferentes identificadores de celda, para asegurarme de que no estaba reutilizando celdas desde una tabla diferente o algo así. Estoy registrando estos identificadores con [tableView registerClass: forCellReuseIdentifier:]

Si lo entiendo, este método solo debería devolver las celdas creadas previamente que se hayan movido fuera de la pantalla (ocultas, es decir, pueden ser reutilizadas). Entonces, ¿cómo es que devuelve una celda la primera vez que se llama?


Editar : Entonces la confusión estaba usando [tableView dequeueReusableCellWithIdentifier: forIndexPath:] lugar de [tableView dequeueReusableCellWithIdentifier:] (el primero requiere registrar el identificador, el segundo devolverá nil si no hay ninguno disponible, el comportamiento que esperaba más arriba).

Sin embargo, me di count de que cuando cambié mi código para usar [tableView dequeueReusableCellWithIdentifier:] , crea una nueva celda, y its contentView.frame tiene un ancho de 320 (ancho total). Antes, cuando hice dequeue...forIndexPath daría un ancho de 302, o el ancho visual / "real" de la celda. ¿Por qué es esto?

Además, ¿hay alguna manera de especificar el estilo de UITableViewCells regstienetworking para su reutilización?


Solución : Así que encontré este subprocess UITableView cell.contentView.bounds.size.width Changes With Cell Reuse , que dice que cuando configura la máscara de autoría a UIViewAutoresizingFlexibleLeftMargin, se corrige cuando intenta hacer un posicionamiento relativo (el ancho de contentView inicialmente es el ancho total , pero cuando lo presionas, se networkinguce, por lo que si haces los cálculos correctamente, seguirá apareciendo correctamente).

Estaba colocando un UISwitch a la derecha, y cuando instalé la máscara de autorrealización, funciona cuando se muestra por primera vez, pero se desplaza sobre otros ~ 20 píxeles cuando lo cambio. No sé qué causó ese cambio extra, pero terminé resolviéndolo simplemente configurando UISwitch como AccessView de la celda.

(Esto está parcialmente fuera del tema de la pregunta original, pero si alguien tropieza con esto, tal vez sería útil). Para cualquier persona que se pregunte específicamente sobre la pregunta original, la respuesta está debajo de la primera edición.

Cuando llama a [tableView registerClass: forCellReuseIdentifier:] , le está enseñando a la tabla qué hacer cuando más tarde utilice el ReuseIdentifier especificado. Entonces, cuando llame más tarde a [tableView dequeueReusableCellWithIdentifier:] :

A. Obtenga una celda que se creó anteriormente y que actualmente no se está utilizando

O

B. Crea una celda nueva de la class que especificaste

Entonces, cuando elimines, siempre obtendrás una instancia. Si desea crear nuevas instancias de celdas usted mismo con initWithStyle:reuseIdentifier: entonces no debe registrar una class con la vista de tabla. Alternativamente, deje el logging y agregue lógica para especificar todo lo que necesita configurarse (y considere usar varias classs de celdas diferentes y reutilizar los identificadores).

porque la primera vez que la celda es nula es por eso que se llama:

 if (!cell) { NSLog(@"New cell"); cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier]; } 

pero luego, si la celda ya está list para su reutilización y, básicamente, no es nula, devuelve la celda y no golpea la instrucción if anterior

De los documentos de Apple en https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006943

Llame a este método desde su object fuente de datos cuando se le solicite proporcionar una nueva celda para la vista de tabla. Este método elimina una celda existente si hay una disponible o crea una nueva utilizando el file de class o nib que registró anteriormente. Si no hay una celda disponible para reutilizar y no registró un file de class o nib, este método devuelve nil.

El método de dequeue

  1. Devuelva una celda reciclada si hay una disponible.

  2. Cree una nueva celda si registró una (mencionó que hizo esto)

  3. Si ninguno de estos es verdadero, devuelve cero

Supongo que si eliminas el logging (que puede estar oculto en un xib), obtendrás el resultado nulo.

si ves UITableView.h

A partir de iOS 6, los clientes pueden registrar una nib o class para cada celda.

Si todos los identificadores de reutilización están registrados, use el más dequeueReusableCellWithIdentifier:forIndexPath : dequeueReusableCellWithIdentifier:forIndexPath : para garantizar que se devuelva una instancia de celda.

Las instancias devueltas del nuevo método de eliminación de queues también tendrán el tamaño adecuado cuando se devuelvan.

 (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0); (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);