在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:
我怀疑,这是做的很像这里的其他答案(暂时禁用UIView
animation/核心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() } }