2012-03-21 17 views
5

He creado un prototipo de celda con el identificador "mainViewTableCell" en el archivo del guión gráfico y he conectado la vista de tabla principal con una clase de controlador personalizada llamada "NTTableViewController". He implementado la función "tableView cellForRowAtIndexPath" en NTTableViewController.m de la siguiente manera:¿Sigue obteniendo nil de dequeueReusableCellWithIdentifier?


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString* MAINVIEW_CELLIDENTIFIER = @"mainViewTableCell"; 
    UITableViewCell *newCell = [tableView dequeueReusableCellWithIdentifier: MAINVIEW_CELLIDENTIFIER]; 

    if (newCell == nil) { 
     newCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: MAINVIEW_CELLIDENTIFIER]; 
     [newCell autorelease]; 
     newCell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 

    NTContactItem* currentItem = [self.contactItemContainer objectInContainerAtIndex: indexPath.row]; 
    NSString* firstName = currentItem.firstName; 
    NSString* lastName = currentItem.lastName; 

    NSString* fullName = [firstName stringByAppendingFormat: lastName];  
    [newCell.textLabel setText: fullName]; 
    [newCell.detailTextLabel setText: currentItem.mobilePhone]; 

    return newCell; 
} 

Pero i manteniendo conseguir nula de dequeueReusableCellWithIdentifier y tienen que crear una nueva instancia de la célula cada vez.

Entonces, ¿qué pasa?

El código: project

Gracias a todos de antemano.

+0

¿Seguro que establece el identificador para esta célula prototipo precisamente a esa misma cadena en el guión gráfico? –

+0

@FirozeLafeer Estoy seguro. De hecho, lo revisé primero cuando encontré el problema. –

Respuesta

26

Con guiones gráficos y vistas de tabla que tienen celdas de prototipo, [tableView dequeueReusableCellWithIdentifier:] no debe devolver nada. Incluso si esta es la primera celda, y ya no hay celdas en la cola de reutilización, la vista de tabla creará una nueva instancia de su celda de prototipo y la devolverá.

En su caso, el problema era algo totalmente diferente (descargué su proyecto porque era realmente curioso).

En el delegado de su aplicación en su método application:didFinishLaunchingWithOptions:, está reinicializando este tableviewcontroller. Cuando llame al [masterController init], esto llama al [super init], que a su vez llama al [UITableViewController initWithStyle:].

Esto hace que el controlador cree una nueva UITableView, que es diferente de la que está en su guión gráfico. Ese nuevo UITableView no tiene celdas de prototipo, y es por eso que dequeueReusableCellWithIdentifier: está regresando a cero.

La lección, por supuesto, es no volver a inicializar un objeto Objective-C que ya se ha inicializado. Cuando su controlador de vista de tabla se carga desde el guión gráfico, el mecanismo de carga lo inicializará con initWithCoder:. Entonces, si necesita hacer algún trabajo de inicialización personalizado (como configurar ese NSMutableArray en su caso), simplemente anule initWithCoder: y/o awakeFromNib.

Puede anular estos métodos según sea necesario, pero no los llame al. El mecanismo de carga Storyboard/nib llamará a initWithCoder: y awakeFromNib.

Si todo es correcto, no es necesario crear celdas programáticamente aquí. Este código no debería ser necesario:

// This bit is unnecessary with storyboards:  
if (newCell == nil) { 
    newCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: MAINVIEW_CELLIDENTIFIER]; 
    [newCell autorelease]; 
    newCell.selectionStyle = UITableViewCellSelectionStyleNone; 
} 

Espero que ayude.

+0

Todo funciona bien ahora. La razón para llamar a [masterController init] es que descubrí que el init de masterController no se llamó en absoluto, dejando la propiedad NSMutableArray sin inicializar. No sabía que initWithCoder puede hacer lo mismo que init y se llamará automáticamente durante el proceso de carga del storyboard. Y necesito aprender más sobre el mecanismo de carga del archivo storyboard/nib. ¡Gracias! –

+0

Esto me estaba volviendo loco todo el día. Estaba llamando una inicialización personalizada (fuente anterior a los guiones gráficos) desde una transición de fuente hasta el destino que estaba recreando la vista de tabla tal como se muestra aquí. Una vez que pasé los valores usando el método prepareForSegue, todos mis reuseIdentifiers funcionaron correctamente. Gracias Firoze! –

+0

tuve el mismo problema, e instalé mi TableViewcontroller utilizando el storyboard instatiateViewControllerWithIdentifier: y ahora todo funciona bien – Claus

1

Las celdas de tabla solo se vuelven reutilizables cuando están ocultas, por lo que solo debe tener el número de celdas que está mostrando actualmente en la memoria. ¿Cuántas celdas está mostrando y cuántas están asignadas?

+0

Creé un nuevo proyecto utilizando la plantilla "Aplicación de detalles maestros" proporcionada por Xcode. La función dequeueReusableCellWithIdentifier devolvió algo pero nada cuando se crea la primera celda. ¿Porque? –

2

Después de leer la respuesta de @Firoze, solucioné mi problema que me había atormentado durante días ... y encontré otra solución. Sé que la pregunta ya ha sido respondida, pero esto puede ayudar a alguien.

En mi caso, he hecho algunas refactorizaciones (he extraído un nuevo TableViewController), y después obtuve cero células devueltas desde dequeueReusableCellWithIdentifier.

La corrección para mí era hacer esto en lugar de llamar alloc/init en mi ViewController en didSelectRowAtIndexPath:

UIStoryboard* sb = [UIStoryboard storyboardWithName:@"MainStoryboard" 
               bundle:nil]; 

MyTableViewController* controller = [sb instantiateViewControllerWithIdentifier: 
            @"MyTableViewController"]; 

(Luego llamo [self.navigationController pushViewController:controller animated:YES]; - no la manera más limpia quizá pero funciona)

1

Justo a caso podría ayudar a alguien en el futuro ... En mi caso, olvidé cambiar el contenido de TableView (Guión gráfico) de "Células estáticas" a "Prototipos dinámicos".

0

Causa típica:

[tableView dequeueReusableCellWithIdentifier: @"id"]; no coincide con Xcode> Atributo Inspector>Tabla celular>Identificador> Identificación del

Cuestiones relacionadas