ReloadItemsAtIndexPathsが呼び出された後、UICollectionViewはアイテムをアニメーション化します(フェードアニメーション)。
このアニメーションを回避する方法はありますか?
iOS 6
これを試すこともできます:
UICollectionView *collectionView;
...
[UIView setAnimationsEnabled:NO];
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:^(BOOL finished) {
[UIView setAnimationsEnabled:YES];
}];
また、UIViewアニメーションブロックでperformBatchUpdates
をラップすると、デフォルトのアニメーションの代わりにUIViewアニメーションが使用されるため、アニメーション期間を次のように0に設定できることもわかりました。
[UIView animateWithDuration:0 animations:^{
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:nil];
}];
これは、挿入および削除中にiOS 7の弾力のあるアニメーションを使用する場合に特に便利です。
IOS 7以降をターゲットにしている場合は、新しいUIView
メソッドperformWithoutAnimation:
。ボンネットの下では、これはここの他の回答とほぼ同じことをしていると思われます(一時的にUIView
アニメーション/コアアニメーションアクションを無効にします)が、構文はすてきできれいです。
したがって、特にこの質問については...
目的C:
[UIView performWithoutAnimation:^{
[self.collectionView reloadItemsAtIndexPaths:indexPaths];
}];
Swift:
UIView.performWithoutAnimation {
self.collectionView.reloadItemsAtIndexPaths(indexPaths)
}
もちろん、この原則は、変更がnotアニメーションであることを確認したいあらゆる状況に適用できます。 。
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に取り組んでいて、同じ質問をしていたので、これは同じ問題に遭遇した人のためにここにあります。
ICollectionViewのカテゴリ を作成して、まさにそれを行いました。秘Theは、リロード中にすべてのアニメーションを無効にすることです。
if (!animated) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
}
[self reloadItemsAtIndexPaths:indexPaths];
if (!animated) {
[CATransaction commit];
}
ここにSwift 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
})
}
}
- (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ドルを追加するために、選択した回答の両方のバージョンを試してみましたが、元の方法は私の目的によりよく機能しました。ユーザーが特定の週にカレンダーを入力し、前後にスワイプしてリストをフィルタリングするために個々の日を選択できるようにする無限スクロールカレンダービューで作業しています。
私の実装では、古いデバイスでパフォーマンスを維持するには、カレンダービューを表す日付の配列を比較的小さくする必要があります。つまり、約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];
extension UICollectionView {
func reloadWithoutAnimation(){
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
self.reloadData()
CATransaction.commit()
}
}