ios UICollectionView 动画数据更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13272315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:07:10  来源:igfitidea点击:

UICollectionView animate data change

iosuicollectionview

提问by Nimrod7

In my Project I use UICollectionView to display a grid of icons.

在我的项目中,我使用 UICollectionView 来显示图标网格。

The user is able to change the ordering by clicking a segmented control which calling a fetch from core data with different NSSortDescriptor.

用户可以通过单击分段控件来更改排序,该控件使用不同的 NSSortDescriptor 从核心数据中调用提取。

The amount of data is always the same, just ending up in different sections / rows:

数据量总是相同的,只是在不同的部分/行中结束:

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

The problem is that reloadData doesn't animate the change, UICollectionView just pops with the new data.

问题是 reloadData 不会为更改设置动画, UICollectionView 只是弹出新数据。

Should I keep track in which indexPath a cell was before and after change, and use [self.collectionView moveItemAtIndexPath: toIndexPath:] to perform the animation for the change or there is a better method ?

我应该跟踪单元格在更改之前和之后在哪个 indexPath 中,并使用 [self.collectionView moveItemAtIndexPath: toIndexPath:] 为更改执行动画还是有更好的方法?

I didn't get much into subclassing collectionViews so any help will be great...

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

Thanks, Bill.

谢谢,比尔。

采纳答案by Stripes

reloadData doesn't animate, nor does it reliabably do so when put in a UIView animation block. It wants to be in a UICollecitonView performBatchUpdates block, so try something more like:

reloadData 不会动画,也不会在放入 UIView 动画块时可靠地进行动画。它想在 UICollecitonView performBatchUpdates 块中,所以尝试更像:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
    // do something on completion 
}];

回答by paulmelnikow

Wrapping -reloadDatain -performBatchUpdates:does not seem to cause a one-section collection view to animate.

包装-reloadData-performBatchUpdates:似乎并没有引起一个截面集合视图动画。

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

However, this code works:

但是,此代码有效:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];

回答by Yariv Nissim

This is what I did to animate reload of ALL SECTIONS:

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

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

Swift 3

斯威夫特 3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)

回答by Gabriel Wamunyu

For Swift users, if your collectionview only has one section:

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

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

As seen on https://stackoverflow.com/a/42001389/4455570

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

回答by nemesis

Reloading the whole collection view inside a performBatchUpdates:completion:block does a glitchy animation for me on iOS 9 simulator. If you have a specific UICollectionViewCellyou want do delete, or if you have it's index path, you could call deleteItemsAtIndexPaths:in that block. By using deleteItemsAtIndexPaths:, it does a smooth and nice animation.

在一个performBatchUpdates:completion:块内重新加载整个集合视图会在 iOS 9 模拟器上为我做一个有问题的动画。如果您有UICollectionViewCell要删除的特定内容,或者您​​有它的索引路径,则可以deleteItemsAtIndexPaths:在该块中调用。通过使用deleteItemsAtIndexPaths:,它可以制作流畅而漂亮的动画。

UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
    // or...
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];

回答by Victor Engel

The help text says:

帮助文本说:

Call this method to reload all of the items in the collection view. This causes the collection view to discard any currently visible items and redisplay them. For efficiency, the collection view only displays those cells and supplementary views that are visible. If the collection data shrinks as a result of the reload, the collection view adjusts its scrolling offsets accordingly. You should not call this method in the middle of animation blocks where items are being inserted or deleted. Insertions and deletions automatically cause the table's data to be updated appropriately.

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

I think the key part is "causes the collection view to discard any currently visible items". How is it going to animate the movement of items it has discarded?

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