84

在我的项目中,我使用 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:] 来执行更改的动画还是有更好的方法?

我对子类化 collectionViews 没有太多了解,所以任何帮助都会很棒......

谢谢,比尔。

4

6 回答 6

146

包裹似乎不会导致单节集合视图动画-reloadData-performBatchUpdates:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:nil];

但是,此代码有效:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
于 2013-03-01T19:51:53.923 回答
74

reloadData 没有动画,当放入 UIView 动画块时也不会可靠地这样做。它想在 UICollecitonView performBatchUpdates 块中,所以尝试更像:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
    // do something on completion 
}];
于 2012-11-28T17:44:19.830 回答
68

这就是我为重新加载所有部分所做的动画:

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];

斯威夫特 3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)
于 2013-05-10T16:50:23.693 回答
12

对于 Swift 用户,如果您的 collectionview 只有一个部分:

self.collectionView.performBatchUpdates({
                    let indexSet = IndexSet(integersIn: 0...0)
                    self.collectionView.reloadSections(indexSet)
                }, completion: nil)

https://stackoverflow.com/a/42001389/4455570所示

于 2018-02-27T21:51:19.363 回答
3

在 iOS 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];
于 2015-09-30T10:25:58.637 回答
1

帮助文本说:

调用此方法以重新加载集合视图中的所有项目。这会导致集合视图丢弃任何当前可见的项目并重新显示它们。为了提高效率,集合视图只显示那些可见的单元格和补充视图。如果集合数据由于重新加载而缩小,集合视图会相应地调整其滚动偏移量。您不应在插入或删除项目的动画块中间调用此方法。插入和删除会自动导致表的数据得到适当的更新。

我认为关键部分是“导致集合视图丢弃任何当前可见的项目”。它将如何为它丢弃的物品的运动设置动画?

于 2013-04-19T18:20:46.643 回答