2012-04-17 9 views
7

Tengo un UITableView normal con 4 filas, cada una con una altura de 50. Cuando presiono la cuarta fila, inserto una quinta fila con una altura de 80 utilizando UITableViewRowAnimationTop. Hasta aquí todo bien.La animación se ve incómoda al eliminar una celda cuya altura es mayor que otras celdas

Quiero eliminar la quinta fila cuando se vuelve a presionar la cuarta fila. Pero cuando borro la fila usando UITableViewRowAnimationTop (o cualquier otro estilo de animación para el caso), la animación se ve muy incómoda: la animación comienza pero la celda desaparece abruptamente antes de que la animación se complete. (Esto solo es aparente cuando usa celdas que tienen un color de fondo. Puede ver que la mitad inferior de la celda desaparece repentinamente en lugar de desaparecer debajo de la celda de arriba).

El código es algo como esto:

[self.tableview beginupdates]; 
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop]; 
[self.tableview endupdates]; 

Las alturas de fila son proporcionadas por el método tableView:heightForRowAtIndexPath:.

Este problema no ocurre cuando todas las filas tienen la misma altura o cuando la fila que se elimina es más corta que las otras filas.

Creo que una solución es cambiar la altura de la quinta celda a 50 antes de eliminarlo, pero yo prefiero no hacer that.Please ayudar a

Respuesta

0

¿Ha intentado hacerlo sin iniciar/endUpdates? Recuerdo vagamente usar a los que hacen las cosas raras una vez.

¿Ha intentado hacer un reloadRowsAtIndexPaths: para la siguiente fila ? Suponiendo que hay uno, eso es.

¿Está seguro de que la fuente de datos se comporta correctamente en términos de respuesta heightForRow en el punto donde realiza la llamada deleteRowsAt? (Por ejemplo, puede configurar una bandera para indicar que la cosa ya no está visible después de la llamada de eliminación, lo que puede ocasionar que la nueva fila tenga una altura incorrecta)

1

Me encontré con este problema esta mañana. Básicamente, terminé manejando la animación yo mismo, luego eliminé la celda una vez que la animación se completó. Aquí hay algo de código para mostrar cómo lo hice:

@property (nonatomic, strong) NSArray *tableData; 
@property (nonatomic, strong) NSMutableDictionary *deletedItems; 
... 

- (void)deleteItemForCell:(UITableViewCell *)cell 
{ 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 
    NSObject *item = self.tableData[indexPath.row]; 

    NSNumber *rowKey = @(indexPath.row); 

    __weak id weakSelf = self; 
    [CATransaction setCompletionBlock:^{ 
     @synchronized(weakSelf) { 
      [self.deletedItems removeObjectForKey:rowKey]; 
      [self.tableData removeObject:item]; 
      [self.tableView deleteRowsAtIndexPaths:@[indexPath] 
            withRowAnimation:UITableViewRowAnimationNone]; 
     } 
    }]; 
    self.deletedItems[rowKey] = item; 

    [self.tableView beginUpdates]; 
    [self.tableView endUpdates]; 

    [CATransaction commit]; 
} 

- (CGFloat)tableView:(UITableView *)tableView 
    heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (self.deletedItem[@(indexPath.row)]) { 
     return 0; 
    } 
    return CELL_HEIGHT; 
} 

Las pistas de código eliminan los elementos de la estructura de datos e informa a la mesa de actualizar. Cualquier elemento en la estructura de datos eliminados obtendrá una altura de 0, lo que dará como resultado una animación de "colapsar".

El código utiliza una CATransaction para saber cuándo se completó la animación. Una vez que se completa, el elemento se elimina de la estructura de datos tableData y se elimina de la tabla, sin ninguna animación.

NOTA:

  • No estoy seguro de si se requiere la sincronizada, pero parecía buena idea tener, ya que estamos tratando con artículos de forma asíncrona eliminación.
  • Intenté utilizar el objeto indexPath como la clave del diccionario, pero no pareció funcionar. Usó la fila en su lugar.

Espero que esto ayude.

1

El uso de una UITableViewRowAnimationMiddle me hizo un poco menos terrible.

Del mismo modo, me di cuenta de que con UITableViewRowAnimationTop, la altura más allá de la altura de celda predeterminada de las tablas aparece/desaparece sin animación. Así que si su altura de la fila tableview es de 44, pero se animan en una celda con altura de 74, será inmediatamente mostrar 30, y luego animar en los restantes 44.

Con UITableViewRowAnimationMiddle el contenido celular en anima muy bien, pero el borde de la celda es defectuoso durante la duración de la animación, que originalmente aparece en 30, y luego anima los 44 restantes.

+0

Aquí estamos en 2017 y este problema aún persiste en tableWiews. 'Middle' de hecho anima el contenido mucho más sensatamente que' Top'. – DanBlakemore

Cuestiones relacionadas