uitableview ios6

Configuración del estilo de UITableViewCell al usar iOS 6 UITableView dequeueReusableCellWithIdentifier: forIndexPath:



ios6 (6)

Estoy tratando de encontrar la manera de configurar el UITableViewCellStyle cuando use los nuevos métodos en iOS 6 para UITableView .

Anteriormente, cuando creaba una UITableViewCell , cambiaba la enumeración UITableViewCellStyle para crear diferentes tipos de celdas predeterminadas al llamar a initWithStyle: pero por lo que puedo deducir, ya no es el caso.

La documentación de Apple para los estados UITableView :

Valor devuelto: un objeto UITableViewCell con el identificador de reutilización asociado. Este método siempre devuelve una celda válida.

Discusión : por motivos de rendimiento, la fuente de datos de una vista de tabla generalmente debería reutilizar objetos UITableViewCell cuando asigna celdas a filas en su método tableView: cellForRowAtIndexPath :. Una vista de tabla mantiene una cola o lista de objetos UITableViewCell que la fuente de datos ha marcado para su reutilización. Llame a este método desde su objeto fuente de datos cuando se le pida que proporcione una nueva celda para la vista de tabla. Este método descuenta una celda existente si hay una disponible o crea una nueva basada en el archivo de clase o punta que usted registró anteriormente.

Importante : debe registrar una clase o archivo nib utilizando el método registerNib: forCellReuseIdentifier: o registerClass: forCellReuseIdentifier: antes de llamar a este método.

Si registró una clase para el identificador especificado y se debe crear una nueva celda, este método inicializa la celda llamando a su método initWithStyle: reuseIdentifier :. Para celdas basadas en plumilla, este método carga el objeto de celda del archivo nib provisto. Si una celda existente estaba disponible para su reutilización, este método llama al método prepareForReuse de la celda.

Así es como se ve mi nueva cellForRowAtIndexPath después de implementar los nuevos métodos:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"cell_identifier"; [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; return cell; }

El código que tengo hasta ahora funciona bien, pero siempre devuelve el estilo predeterminado. ¿Cómo puedo cambiar esto para poder crear celdas con los otros estilos como UITableViewCellStyleDefault , UITableViewCellStyleValue1 , UITableViewCellStyleValue2 y UITableViewCellStyleSubtitle ?

No quiero subclasificar UITableViewCell , solo quiero cambiar el tipo predeterminado como podría hacerlo antes de iOS 6. Parece extraño que Apple proporcione métodos mejorados pero con documentación mínima para respaldar su implementación.

¿Alguien ha dominado esto o se ha encontrado con un problema similar? Estoy luchando por encontrar cualquier información razonable en absoluto.


La respuesta de Bolot es la correcta. Simple y no es necesario crear ningún archivo XIB.

Solo quería actualizar su respuesta para quien sea que esté usando Swift en lugar de Objective-C:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: .value1, reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }


Mi solución a esto es llamar a initWithStyle: reuseIdentifier: después de obtenerlo usando [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath] . Después de todo, init es simplemente otro selector, y el compilador no tiene restricciones para llamarlo a un objeto ya inicializado. Sin embargo, se quejará de no usar el resultado de llamar a init, por lo que hago:

UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]; cell = [cell initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellId"];

Me imagino que esto no funcionará en Swift ...


Otra alternativa que guarda un archivo es crear un Nib y usar registerNib:forCellReuseIdentifier: lugar.

Hacer el Nib es fácil: crea un nuevo archivo .xib en Interface Builder. Eliminar la vista predeterminada Agregue un objeto Celda de vista de tabla. Usando el Inspector de Atributos, cambie el estilo de la celda. (Aquí también tiene la oportunidad de personalizar aún más la celda ajustando otros atributos).

Luego, en el método viewDidLoad su controlador de vista de viewDidLoad , llame a algo como:

[self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"];


Puede evitar una subclase extraña mediante el uso del generador de interfaz del guión gráfico:

  1. En la vista del Guión gráfico, seleccione la celda del prototipo de celda de la vista de tabla (en la vista de tabla)
  2. En la vista Utilidades, en el inspector de Atributos, modifique el valor de Estilo
  3. (Opcionalmente) Modifique otros valores como Selección y Accesorio

El nuevo iOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath: usa esos valores al asignar nuevas celdas y devolverlas. (Probado en una compilación iOS 6.0 utilizando Xcode 4.5.2)


Sé que dijiste que no querías crear una subclase, pero parece inevitable. Basado en el código ensamblador mientras se prueba en el simulador iOS 6.0, UITableView crea nuevas instancias de UITableViewCell (o sus subclases) al realizar

[[<RegisteredClass> alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:<ReuseIdentifier>]

En otras palabras, el estilo enviado ( UITableViewCellStyleDefault ) parece estar codificado. Para evitar esto, deberá crear una subclase que anule el inicializador predeterminado initWithStyle:reuseIdentifier: y pase el estilo que desea usar:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { // ignore the style argument, use our own to override self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; if (self) { // If you need any further customization } return self; }

Además, podría ser mejor enviar registerClass:forCellReuseIdentifier: en viewDidLoad , en lugar de hacerlo cada vez que se solicite una celda:

- (void)viewDidLoad { [super viewDidLoad]; [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>]; }


dequeueReusableCellWithIdentifier no está en desuso por lo que no está obligado a utilizar el nuevo dequeueReusableCellWithIdentifier:forIndexPath:

Utilice la nueva forma junto con el método de registro apropiado (en viewDidLoad) si está utilizando una clase de celda personalizada, pero use la antigua si desea usar una de las enumeraciones UITableViewCellStyle.