96

UICollectionView は、 reloadItemsAtIndexPaths が呼び出された後に項目をアニメーション化します (フェード アニメーション)。

このアニメーションを回避する方法はありますか?

iOS6

4

10 に答える 10

163

これを試すこともできます:

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 の弾力のあるアニメーションを使用したい場合、これは非常にクールです!

于 2013-02-25T14:07:45.727 に答える
22

UICollectionView は、 reloadItemsAtIndexPaths が呼び出された後に項目をアニメーション化します (フェード アニメーション)。

このアニメーションを回避する方法はありますか?

iOS6

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 に取り組んでいて、同じ質問があったので、これは同じ問題に遭遇した人のためにここにあります.

于 2018-02-09T03:07:49.710 に答える
8

まさにそれを行うために、UICollectionView にカテゴリを作成しました。秘訣は、リロード中にすべてのアニメーションを無効にすることです。

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

[self reloadItemsAtIndexPaths:indexPaths];

if (!animated) {
    [CATransaction commit];
}
于 2013-01-19T10:56:37.333 に答える
6
extension UICollectionView {
    func reloadWithoutAnimation(){
        CATransaction.begin()
        CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
        self.reloadData()
        CATransaction.commit()
    }
}
于 2017-01-03T07:02:35.857 に答える
5

performBatchUpdatesこれは、アニメーションなしの Swift 3 バージョン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

        })
    }
}
于 2017-05-31T09:46:08.260 に答える
2
- (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];
    }

}
于 2014-01-25T16:54:33.213 に答える
1

0.02ドルを追加するために、選択した回答の両方のバージョンを試しましたが、元の方法の方が目的に適していました。ユーザーが特定の週にカレンダーに入り、前後にスワイプしてリストをフィルタリングするために個々の日を選択できる無限スクロールカレンダービューに取り組んでいます。

私の実装では、古いデバイスでのパフォーマンスを維持するために、カレンダー ビューを表す日付の配列を比較的小さく保つ必要があります。つまり、約 5 週間分の日付を保持する必要があり、ユーザーは 3 週目の真ん中にいます。2 番目のアプローチを使用する際の問題は、アニメーションなしでコレクション ビューを中央にスクロールする必要がある 2 番目のステップがあることです。これにより、ブロックされたベース アニメーションで何らかの理由で非常にぎざぎざの外観になります。

私のコード:

[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];
于 2014-06-08T01:56:42.757 に答える
0

使用する代わりに、reloadData()アニメーションなしですべての可視セルをリロードするには、次を試してください。

self.collectionView.reloadItems(at: self.collectionView.indexPathsForVisibleItems)
于 2021-02-20T18:37:54.337 に答える