UITableView 中动画插入/删除的 2 个 NSArray 的区别
Posted
技术标签:
【中文标题】UITableView 中动画插入/删除的 2 个 NSArray 的区别【英文标题】:Difference of 2 NSArray's for animated insert/delete in UITableView 【发布时间】:2010-03-13 20:04:43 【问题描述】:在我的应用程序的某个时刻,我有一个 NSArray,它的内容发生了变化。这些内容显示在 UITableView 中。我正在尝试找到一种方法来查找 NSArray 之前和之后的内容之间的差异,以便我可以将正确的 indexPaths 传递给 insertRowsAtIndexPaths:withRowAnimation: 和 deleteRowsAtIndexPaths:withRowAnimation: 以便使更改很好地动画化。有什么想法吗?
谢谢
【问题讨论】:
【参考方案1】:这是我尝试过的方法,它似乎有效,如果有人有更好的方法,我很想看看。
[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】:这个 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];
);
【讨论】:
以上是关于UITableView 中动画插入/删除的 2 个 NSArray 的区别的主要内容,如果未能解决你的问题,请参考以下文章
删除和插入具有不同高度的单元格时,UITableView 动画故障