避免reloadItemsAtIndexPaths后UICollectionView动画(Avoid

2019-07-17 16:58发布

reloadItemsAtIndexPaths被称为(动画渐变)后UICollectionView动画项目。

是否有办法避免这种动画?

iOS 6的

Answer 1:

你也可以试试这个:

UICollectionView *collectionView;

...

[UIView setAnimationsEnabled:NO];

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

编辑:

我还发现,如果你换performBatchUpdates在一个UIView动画块,UIView的动画则使用默认的动画,而不是,所以你可以设定动画的持续时间为0,像这样:

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

如果你想插入过程中使用的iOS 7弹性动画,并删除这是额外的爽!



Answer 2:

值得一提的是,如果您的目标的iOS 7及以上的,你可以使用新UIView方法performWithoutAnimation: 我猜想,在引擎盖下,这是做大致相同这里其他的答案(暂时禁用UIView动画/核心动画动作),但语法是非常干净的。

因此,对于特别是这个问题...

Objective-C的:

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


迅速:

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


当然,这个原则可以应用于要确保变更没有设置动画的任何情况。



Answer 3:

reloadItemsAtIndexPaths被称为(动画渐变)后UICollectionView动画项目。

是否有办法避免这种动画?

iOS 6的

我假设你正在使用的FlowLayout。 既然你想摆脱的动画渐变的,试试这个:

import UIKit

class NoFadeFlowLayout: UICollectionViewFlowLayout {

    override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attrs = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath)
        attrs?.alpha = 1.0
        return attrs
    }

    override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attrs = super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath)
        attrs?.alpha = 1.0
        return attrs
    }

}

这是一个非常古老的问题,所以你可能不针对iOS 6的了。 我亲自工作tvOS 11有同样的问题,所以这是这里的人谁具有同样的问题走来。



Answer 4:

我写了一个关于UICollectionView类别来做到这一点。 诀窍是禁用,而重装所有的动画:

if (!animated) {
    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
}

[self reloadItemsAtIndexPaths:indexPaths];

if (!animated) {
    [CATransaction commit];
}


Answer 5:

这里是一个斯威夫特3版performBatchUpdates没有动画的UICollectionView 。 我发现这不是更好地为我collectionView.reloadData()因为它降低了电池交换时记录插入。

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

        })
    }
}


Answer 6:

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

}


Answer 7:

我想补充我的$ 0.02时,我尝试了选择的答案的两个版本,和原始的方式,我的目的更好地工作。 我的工作,允许用户输入在给定的周日历,然后刷卡来回选择个别天用于过滤列表的无限滚动日历视图。

我在执行中,为了让事情高性能旧设备上表示日历视图日期的阵列必须保持相对较小,这意味着持有约5星期的日期,与第3周在中间的用户。 与使用第二种方法的问题是,还有就是你必须滚动集合视图回到中间没有动画,这是个非常锯齿状外观出于某种原因与阻断的碱动画的第二步。

我的代码:

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


Answer 8:

extension UICollectionView {
    func reloadWithoutAnimation(){
        CATransaction.begin()
        CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
        self.reloadData()
        CATransaction.commit()
    }
}


文章来源: Avoid animation of UICollectionView after reloadItemsAtIndexPaths