在我的项目中,我使用UICollectionView显示图标网格。
用户可以通过单击一个分段控件来更改排序,该控件使用不同的NSSortDescriptor调用核心数据的提取。
数据量始终相同,只是在不同的部分/行中结束:
- (IBAction)sortSegmentedControlChanged:(id)sender {
_fetchedResultsController = nil;
_fetchedResultsController = [self newFetchResultsControllerForSort];
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
[self.collectionView reloadData];
}
问题是reloadData没有为更改设置动画,UICollectionView只是弹出新数据。
我应该跟踪更改前后单元格中的哪个indexPath,并使用[self.collectionView moveItemAtIndexPath:toIndexPath:]来执行更改动画,还是有更好的方法?
我没有太多进入子类化集合视图,所以任何帮助都会很棒......
谢谢, 比尔。
答案 0 :(得分:143)
在-reloadData
中包裹-performBatchUpdates:
似乎不会导致单节集合视图设置动画。
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:nil];
但是,此代码有效:
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
答案 1 :(得分:65)
reloadData不会设置动画,也不会在放入UIView动画块时可靠地执行此操作。它想要在UICollecitonView performBatchUpdates块中,所以尝试更像:
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {}];
答案 2 :(得分:61)
这就是我为动画重新加载所有部分所做的工作:
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];
Swift 3
let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)
答案 3 :(得分:4)
对于Swift用户,如果您的集合视图只有一个部分:
self.collectionView.performBatchUpdates({
let indexSet = IndexSet(integersIn: 0...0)
self.collectionView.reloadSections(indexSet)
}, completion: nil)
答案 4 :(得分:2)
如果您想要更多控制和自定义功能检查this, 它包含对UICollectionViewCell动画的各种方式的非常详细的解释。
答案 5 :(得分:2)
在{9}模块中重新加载performBatchUpdates:completion:
块内的整个集合视图会给我带来一个小故障动画。如果您要删除特定的UICollectionViewCell
,或者如果您有索引路径,则可以在该块中调用deleteItemsAtIndexPaths:
。通过使用deleteItemsAtIndexPaths:
,它可以做出流畅而漂亮的动画。
UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
// or...
[self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];
答案 6 :(得分:1)
帮助文字说:
调用此方法重新加载集合视图中的所有项目。 这会导致集合视图丢弃任何当前可见的项目 并重新显示它们。为了提高效率,仅显示集合视图 那些细胞和可见的补充观点。如果 集合数据由于重新加载而收缩,即集合视图 相应地调整其滚动偏移。你不应该这样称呼 在物品所在的动画块中间的方法 插入或删除。插入和删除会自动导致 表的数据要适当更新。
我认为关键部分是“导致集合视图丢弃任何当前可见的项目”。如何动画它丢弃的物品的动作?
答案 7 :(得分:-4)
对于快速用户来说,这很方便 -
collectionView.performBatchUpdates({
self.collectionView.reloadSections(NSIndexSet(index: index))
}, completion: nil)