2009-08-25 11 views
6

He encontrado algunas publicaciones que son similares a mi problema pero que no son lo mismo.filas duplicadas en la vista de tabla en uitableviewcell

En mi aplicación, el usuario puede navegar entre varias uitableviews para obtener el resultado deseado. Cuando un usuario avanza, luego hacia atrás, luego hacia adelante, etc., se observa que las filas se vuelven a dibujar/reescribir y el texto se vuelve más audaz y audaz.

He encontrado que en algunos de los mensajes esto puede estar relacionado con la forma en que estoy creando las filas, usando un uilable dentro del método cellforrowatindexpath.

¿Hay algo que deba hacer para que las filas no se repoblen/vuelvan a dibujar cada vez que un usuario avanza y retrocede entre las vistas de tabla? ¿Debo agregar algo al código siguiente o agregar algo al método viewwillappear (actualmente hay una 'reloaddata' en la vista que aparecerá para la tabla pero que no parece ser de ayuda)?

Aquí está mi código:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
} 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
    label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
    label.textColor = [UIColor blackColor]; 
    label.backgroundColor = [UIColor clearColor]; 
    label.opaque = NO; 
    label.text = [mapareaArray objectAtIndex:indexPath.row]; 
    [cell.contentView addSubview:label]; 

    CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
    bgView.borderColor = [UIColor clearColor]; 
    bgView.fillColor = [UIColor whiteColor]; 
    bgView.position = CustomCellBackgroundViewPositionSingle; 
    cell.backgroundView = bgView; 
    return cell; 
} 

Respuesta

11

El problema que tiene se debe a esta línea:

[cell.contentView addSubview:label]; 

va a añadir una vista secundaria a la celda de la tabla si se trata de una célula nueva o no . Si se trata de una celda antigua (eliminada del grupo reutilizable), agregará otra subvista a la celda.

En su lugar, debe etiquetar el UILabel, y luego localizarlo con la etiqueta para modificar el contenido de ese UILabel. Añadir (y configurar todos sus atributos) y la etiqueta de la UILabel dentro del si (célula == nil) bloque:

if(cell == nil) { 
    // alloc and init the cell view... 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.tag = kMyTag; // define kMyTag in your header file using #define 
    // and other label customizations 
    [cell.contentView addSubview:label]; // addSubview here and only here 
    ... 
} 

continuación, busque con:

UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 

Y no hay necesidad de volver a añadir como una subvista fuera del bloque if (cell == nil). La subvista ya está allí (y es por eso que reutilizar las vistas de celda es mucho más eficiente, si lo haces correctamente, eso es;).

+0

Muchas gracias por esto. Gran ayuda Una última pregunta sobre esto: no tengo un fondo de programación, así que no estoy seguro de lo que quiere decir con el uso de #define en el archivo de encabezado. ¿Cuál es la sintaxis para hacer esto? Lo he visto antes y he intentado poner '#define kMyTag' en el encabezado, pero esto no funciona ...Supongo que necesita definir kMyTag a un valor pero no está seguro de cuál sería la sintaxis para hacerlo. ¿Puede usted ayudar? – SKayser

1

archivo .h El 'definir' se pone después de las declaraciones import en la parte superior del archivo de cabecera, y fue puesto como 0, porque no sé qué otra manera de definirlo:

#define kMyTag 0 

. m archivo He actualizado esta sección según sus comentarios, pero a) la tabla no está llena, b) cuando el usuario ha navegado a la vista siguiente y vuelve a esta vista falla con un "selector no reconocido enviado a instancia" , yc) Tuve que poner las dos "células de retorno"; entradas o se cae. Creo que tengo cosas en el orden incorrecto y tal vez no inicié las cosas correctamente ???

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     UILabel *label = [[[UILabel alloc] init] autorelease]; 
     label.tag = kMyTag; // define kMyTag in your header file using #define 
     label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
     label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
     label.textColor = [UIColor blackColor]; 
     label.backgroundColor = [UIColor clearColor]; 
     label.opaque = NO; 

     CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
     bgView.borderColor = [UIColor clearColor]; 
     bgView.fillColor = [UIColor whiteColor]; 
     bgView.position = CustomCellBackgroundViewPositionSingle; 
     cell.backgroundView = bgView; 

     [cell.contentView addSubview:label]; // addSubview here and only here 
     return cell; 
    } 
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 
return cell; 
} 
+0

No estoy seguro de si debe usar 0 para el valor de kMyTag. Intente comenzar desde 1, ya que 0 puede ser el valor predeterminado para todo. Después de ese cambio, elimine la celda de retorno dentro del bloque if. – tchen

+0

¡Gracias una vez más! Eso funciona ahora! ¡Aprecia tu tiempo! – SKayser

0

Debe crear una subclase de UITableViewCell para esa célula específica, a continuación, aplicar la lógica para ver si es necesario agregar la subvista a sí mismo cada vez. Además, use PrepareForReuse de UITableviewcell y elimine las subvistas durante ese tiempo antes de aplicar la lógica de si desea agregar un UILabel a su Celda.

Cuestiones relacionadas