Разница 2 NSArray для анимированной вставки / удаления в UITableView - PullRequest
8 голосов
/ 13 марта 2010

В какой-то момент в моем приложении у меня есть NSArray, содержимое которого изменяется. Это содержимое показано в UITableView. Я пытаюсь найти способ найти разницу между содержимым до и после NSArray, чтобы я мог передать правильные indexPaths для insertRowsAtIndexPaths: withRowAnimation: и deleteRowsAtIndexPaths: withRowAnimation: для того, чтобы изменения были хорошо анимированы. Есть идеи?

ТНХ

Ответы [ 2 ]

5 голосов
/ 13 марта 2010

Вот то, что я попробовал, и, кажется, работает, если у кого-то есть что-то лучше, я бы хотел это увидеть.

[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];
2 голосов
/ 15 декабря 2015

Этот вопрос 2010 года я нашел, когда гуглил. Начиная с iOS 5.0, теперь у нас также есть -[UITableView moveRowAtIndexPath:toIndexPath], с которым вы действительно хотите работать. Вот функция, которая сравнивает два массива и генерирует подходящие пути индекса для операций удаления, вставки и перемещения.

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

Пример того, как его использовать. Предположим, вы отображаете таблицу людей, которую вы храните в массиве self.people. Индекс раздела, в котором отображаются люди, равен 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];
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...