2010-03-13 6 views
8

En algún momento de mi aplicación, tengo un NSArray cuyos contenidos cambian. Esos contenidos se muestran en una UITableView. Estoy tratando de encontrar una forma de encontrar la diferencia entre los contenidos de antes y después de NSArray para poder pasar los indexPaths correctos a insertarRowsAtIndexPaths: withRowAnimation: y deleteRowsAtIndexPaths: withRowAnimation: para que los cambios estén muy animados. ¿Algunas ideas?Diferencia de 2 NSArray para inserción/supresión animada en UITableView

THX

Respuesta

5

Aquí es wat que probé y parece que funciona, si alguien tiene algo mejor, me encantaría verlo.

[self.tableView beginUpdates]; 

NSMutableArray* rowsToDelete = [NSMutableArray array]; 
NSMutableArray* rowsToInsert = [NSMutableArray array]; 

for (NSInteger i = 0; i < oldEntries.count; i++) 
{ 
    FDEntry* entry = [oldEntries objectAtIndex:i]; 
    if (! [displayEntries containsObject:entry]) 
     [rowsToDelete addObject: [NSIndexPath indexPathForRow:i inSection:0]]; 
} 

for (NSInteger i = 0; i < displayEntries.count; i++) 
{ 
    FDEntry* entry = [displayEntries objectAtIndex:i]; 
    if (! [oldEntries containsObject:entry]) 
    [rowsToInsert addObject: [NSIndexPath indexPathForRow:i inSection:0]]; 
} 

[self.tableView deleteRowsAtIndexPaths:rowsToDelete withRowAnimation:UITableViewRowAnimationFade]; 
[self.tableView insertRowsAtIndexPaths:rowsToInsert withRowAnimation:UITableViewRowAnimationRight]; 

[self.tableView endUpdates]; 
+0

¡Bien hecho! Sangriento difícil de conseguir esto :) –

2

Esta pregunta de 2010 es lo que encontré cuando estaba buscando en Google. Desde iOS 5.0, ahora también tenemos -[UITableView moveRowAtIndexPath:toIndexPath] que realmente deseas manejar. Aquí hay una función que compara dos arrays y genera indexpaths adecuados para las operaciones de eliminar, insertar y mover.

- (void) calculateTableViewChangesBetweenOldArray:(NSArray *)oldObjects 
             newArray:(NSArray *)newObjects 
            sectionIndex:(NSInteger)section 
           indexPathsToDelete:(NSArray **)indexPathsToDelete 
           indexPathsToInsert:(NSArray **)indexPathsToInsert 
           indexPathsToMove:(NSArray **)indexPathsToMove 
          destinationIndexPaths:(NSArray **)destinationIndexPaths 
{ 

    NSMutableArray *pathsToDelete = [NSMutableArray new]; 
    NSMutableArray *pathsToInsert = [NSMutableArray new]; 
    NSMutableArray *pathsToMove = [NSMutableArray new]; 
    NSMutableArray *destinationPaths = [NSMutableArray new]; 

    // Deletes and moves 
    for (NSInteger oldIndex = 0; oldIndex < oldObjects.count; oldIndex++) { 
     NSObject *object = oldObjects[oldIndex]; 
     NSInteger newIndex = [newObjects indexOfObject:object]; 

     if (newIndex == NSNotFound) { 
      [pathsToDelete addObject:[NSIndexPath indexPathForRow:oldIndex inSection:section]]; 
     } else if (newIndex != oldIndex) { 
      [pathsToMove addObject:[NSIndexPath indexPathForRow:oldIndex inSection:section]]; 
      [destinationPaths addObject:[NSIndexPath indexPathForRow:newIndex inSection:section]]; 
     } 
    } 

    // Inserts 
    for (NSInteger newIndex = 0; newIndex < newObjects.count; newIndex++) { 
     NSObject *object = newObjects[newIndex]; 
     if (![oldObjects containsObject:object]) { 
      [pathsToInsert addObject:[NSIndexPath indexPathForRow:newIndex inSection:section]]; 
     } 
    } 

    if (indexPathsToDelete)  *indexPathsToDelete = [pathsToDelete copy]; 
    if (indexPathsToInsert)  *indexPathsToInsert = [pathsToInsert copy]; 
    if (indexPathsToMove)  *indexPathsToMove =  [pathsToMove copy]; 
    if (destinationIndexPaths) *destinationIndexPaths = [destinationPaths copy]; 
} 

Un ejemplo sobre cómo usarlo. Supongamos que está mostrando una tabla de personas, que guarda en el conjunto self.people. El índice de sección donde se muestran las personas es 0.

- (void) setPeople:(NSArray <Person *> *)newPeople { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.tableView beginUpdates]; 

     NSArray *rowsToDelete, *rowsToInsert, *rowsToMove, *destinationRows; 

     [self calculateTableViewChangesBetweenOldArray:self.people 
               newArray:newPeople 
              sectionIndex:0 
            indexPathsToDelete:&rowsToDelete 
            indexPathsToInsert:&rowsToInsert 
             indexPathsToMove:&rowsToMove 
           destinationIndexPaths:&destinationRows 
     ]; 

     self.people = newPeople; 

     [self.tableView deleteRowsAtIndexPaths:rowsToDelete withRowAnimation:UITableViewRowAnimationFade]; 
     [self.tableView insertRowsAtIndexPaths:rowsToInsert withRowAnimation:UITableViewRowAnimationFade]; 
     [rowsToMove enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull oldIndexPath, NSUInteger idx, BOOL * _Nonnull stop) { 
      NSIndexPath *newIndexPath = destinationRows[idx]; 
      [self.tableView moveRowAtIndexPath:oldIndexPath toIndexPath:newIndexPath]; 
     }]; 

     [self.tableView endUpdates]; 
    }); 
} 
Cuestiones relacionadas