2010-03-13 9 views
8

Irgendwann in meiner Anwendung habe ich ein NSArray, dessen Inhalt sich ändert. Diese Inhalte werden in einer UITableView angezeigt. Ich versuche einen Weg zu finden, den Unterschied zwischen dem Inhalt von vorher und nach dem NSArray zu finden, so kann ich die richtigen indexPaths zu insertRowsAtIndexPaths übergeben: withRowAnimation: und deleteRowsAtIndexPaths: withRowAnimation: um die Änderungen schön animiert zu haben. Irgendwelche Ideen?Unterschied von 2 NSArrays zum animierten Einfügen/Löschen in UITableView

thx

Antwort

5

Hier ist wat ich versucht, und es scheint, zu arbeiten, wenn jemand etwas besser hat, ich es sehen würde gerne.

[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

Gut gemacht! Verdammt schwer, das zu bekommen :) –

2

Diese Frage von 2010 ist, was ich beim googlen fand. Seit iOS 5.0 haben wir jetzt auch -[UITableView moveRowAtIndexPath:toIndexPath], die Sie wirklich auch behandeln möchten. Hier ist eine Funktion, die zwei Arrays vergleicht und geeignete Indexpfade für die Lösch-, Einfüge- und Verschiebeoperationen erzeugt.

- (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]; 
} 

Ein Beispiel, wie man es benutzt. Angenommen, Sie zeigen eine Tabelle mit Personen an, die Sie im Array behalten. Der Abschnittsindex, in dem die Personen angezeigt werden, ist 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]; 
    }); 
} 
Verwandte Themen