在reloadItemsAtIndexPaths之后避免UICollectionView的animation

UICollectionView在reloadItemsAtIndexPaths被调用(淡入淡出animation)后animation的项目。

有没有办法避免这个animation?

iOS 6

你也可以试试这个:

UICollectionView *collectionView; 

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

编辑:

我还发现,如果在UIViewanimation块中包装performBatchUpdates ,将使用UIViewanimation而不是默认animation,因此您可以将animation持续时间设置为0,如下所示:

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

如果你想在插入和删除过程中使用iOS 7弹性animation,这是非常酷的!

值得注意的是,如果你的目标是iOS 7以上,你可以使用新的UIView方法performWithoutAnimation: 我怀疑,这是做的很像这里的其他答案(暂时禁用UIViewanimation/核心animation操作)相同,但语法是很好,干净。

所以对于这个问题,特别是…

Objective-C的:

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

迅速:

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

当然,这个原则可以适用于任何你想确保改变animation的情况。

我在UICollectionView上写了一个类来做到这一点。 诀窍是在重新加载时禁用所有的animation:

 if (!animated) { [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; } [self reloadItemsAtIndexPaths:indexPaths]; if (!animated) { [CATransaction commit]; } 
 - (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]; } } 

为了增加我的$ 0.02,我尝试了所选答案的两个版本,原来的方式对我的目的更好。 我正在处理无限的滚动日历视图,允许用户在给定的星期内input日历,然后来回滑动并select单个date来过滤列表。

在我的实现中,为了保持旧设备上的性能,表示日历视图的date数组必须保持相对较小,这意味着保持约5周的date,用户在第三周中间。 使用第二种方法的问题在于,还有第二步,您必须将集合视图滚动回到没有animation的中间,由于某些原因,阻塞的基础animation会导致非常锯齿状的外观。

我的代码:

 [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]; 

这里是一个Swift 3版本来执行没有animation到UICollectionView 。 我发现这比我的更好的工作比collectionView.reloadData()因为它减less插入logging时的单元格交换。

 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 }) } } 
 extension UICollectionView { func reloadWithoutAnimation(){ CATransaction.begin() CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions) self.reloadData() CATransaction.commit() } }