UICollectionView animate data change

2019-01-30 00:37发布

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

The user is able to change the ordering by clicking a segmented control which calling a fetch from core data with different 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.

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 ?

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

Thanks, Bill.

8条回答
够拽才男人
2楼-- · 2019-01-30 01:04

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 UICollectionViewCell you 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.

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

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
    // or...
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];
查看更多
Rolldiameter
3楼-- · 2019-01-30 01:08

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:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:^(BOOL finished) {}];
查看更多
登录 后发表回答