UICollectionView动画数据更改

时间:2012-11-07 15:02:21

标签: ios uicollectionview

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

我没有太多进入子类化集合视图,所以任何帮助都会很棒......

谢谢, 比尔。

8 个答案:

答案 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)

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

答案 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)