Avoid UICollectionView animations after reloadItemsAtIndexPaths

UICollectionView animate elements after calling reloadItemsAtIndexPaths (fade animation).

Is there any way to avoid this animation?

iOS 6

+61
ios animation ios6 uiview uicollectionview
Dec 30 2018-12-12T00:
source share
7 answers

You can also try the following:

UICollectionView *collectionView; 

...

 [UIView setAnimationsEnabled:NO]; [collectionView performBatchUpdates:^{ [collectionView reloadItemsAtIndexPaths:indexPaths]; } completion:^(BOOL finished) { [UIView setAnimationsEnabled:YES]; }]; 

Edit:

I also found that if you wrap performBatchUpdates in a UIView animation block, the UIView animation is used instead of the default animation, so you can just set the animation duration to 0, for example:

 [UIView animateWithDuration:0 animations:^{ [collectionView performBatchUpdates:^{ [collectionView reloadItemsAtIndexPaths:indexPaths]; } completion:nil]; }]; 

This is great if you want to use iOS 7 animations when inserting and deleting!

+139
Feb 25 '13 at 2:07
source share

It is worth noting that if you focus on iOS 7 and higher, you can use the new UIView performWithoutAnimation: method. I suspect that under the hood this does the same as the other answers here (temporarily disabling UIView / Core Animation), but the syntax is nice and clean.

So, for this question in particular ...

Objective-C:

 [UIView performWithoutAnimation:^{ [self.collectionView reloadItemsAtIndexPaths:indexPaths]; }]; 


Swift:

 UIView.performWithoutAnimation { self.collectionView.reloadItemsAtIndexPaths(indexPaths) } 


Of course, this principle can be applied to any situation in which you want the change to not be animated.

+134
Aug 20 '14 at 11:46
source share

I wrote a category in a UICollectionView to do just that. The trick is to turn off all animations during reboot:

 if (!animated) { [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; } [self reloadItemsAtIndexPaths:indexPaths]; if (!animated) { [CATransaction commit]; } 
+7
Jan 19 '13 at
source share
 - (void)reloadCollectionViewAnimated:(BOOL)animated { if (animated) { [self.collectionView performBatchUpdates:^{ [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; } completion:^(BOOL finished) { }]; } else { [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; [CATransaction commit]; } } 
+1
Jan 25
source share

Just to add my $ 0.02, I tried both versions of the selected answer, and the original way worked better for my purposes. I am working on endlessly viewing a scroll calendar that allows the user to enter a calendar for a given week, and then scroll back and forth and select individual days to filter the list.

In my implementation, in order to maintain performance on older devices, the array of dates representing the calendar view should be relatively small, which means that it should contain dates at 5 weeks, and the user in the middle at the third week. The problem with using the second approach is that there is a second step in which you need to scroll the collection view to the middle without animation, which for some reason creates a very uneven appearance with the base animation blocked.

My code is:

 [UIView setAnimationsEnabled:NO]; [self.collectionView performBatchUpdates:^{ [self.collectionView deleteItemsAtIndexPaths:indexPathDeleteArray]; [self.collectionView insertItemsAtIndexPaths:indexPathAddArray]; } completion:NULL]; [UIView setAnimationsEnabled:YES]; NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:14 inSection:0]; [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; 
+1
Jun 08 '14 at 1:56 on
source share

Here is the Swift 3 version prior to performBatchUpdates without animation before the UICollectionView . I found that this works better for me than collectionView.reloadData() , because it reduced the cell exchange when inserting records.

 func appendCollectionView(numberOfItems count: Int){ // calculate indexes for the items to be added let firstIndex = dataItems.count - count let lastIndex = dataItems.count - 1 var indexPaths = [IndexPath]() for index in firstIndex...lastIndex { let indexPath = IndexPath(item: index, section: 0) indexPaths.append(indexPath) } UIView.performWithoutAnimation { self.collectionView.performBatchUpdates({ () -> Void in self.collectionView.insertItems(at: indexPaths) }, completion: { (finished) -> Void in }) } } 
+1
May 31 '17 at 9:46 a.m.
source share
 extension UICollectionView { func reloadWithoutAnimation(){ CATransaction.begin() CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions) self.reloadData() CATransaction.commit() } } 
0
Jan 03 '17 at 7:02
source share



All Articles