web-dev-qa-db-ja.com

UICollectionViewアニメーションデータの変更

私のプロジェクトでは、UICollectionViewを使用してアイコンのグリッドを表示します。

ユーザーは、異なるNSSortDescriptorを使用してコアデータからフェッチを呼び出すセグメント化されたコントロールをクリックすることにより、順序を変更できます。

データの量は常に同じで、異なるセクション/行に終わるだけです

- (IBAction)sortSegmentedControlChanged:(id)sender {

   _fetchedResultsController = nil;
   _fetchedResultsController = [self newFetchResultsControllerForSort];

   NSError *error;
   if (![self.fetchedResultsController performFetch:&error]) {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   }

   [self.collectionView reloadData];
}

問題は、reloadDataは変更をアニメーション化せず、UICollectionViewが新しいデータでポップするだけであるということです。

セルが変更前と変更後のindexPathを追跡し、[self.collectionView moveItemAtIndexPath:toIndexPath:]を使用して変更のアニメーションを実行するか、より良い方法がありますか?

CollectionViewsのサブクラス化にはあまり興味がなかったので、どんな助けも素晴らしいでしょう...

ありがとう、ビル。

78
Nimrod7

reloadDataはアニメーション化せず、UIViewアニメーションブロックに配置された場合も確実にアニメーション化しません。 UICollecitonView performBatchUpdatesブロックに入れたいので、次のようなものを試してください。

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {}];
67
Stripes

-reloadData-performBatchUpdates:をラップすると、1セクションのコレクションビューがアニメーション化されないようです。

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:nil];

ただし、このコードは機能します。

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
142
paulmelnikow

これは私がすべてのセクションのリロードをアニメーション化するためにしたことです:

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];

Swift

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)
64
Yariv Nissim

Swiftユーザーの場合、コレクションビューにセクションが1つしかない場合:

self.collectionView.performBatchUpdates({
                    let indexSet = IndexSet(integersIn: 0...0)
                    self.collectionView.reloadSections(indexSet)
                }, completion: nil)

https://stackoverflow.com/a/42001389/445557 で見られるように

5
Gabriel Wamunyu

より詳細な制御とカスタマイズ可能な機能チェック this が必要な場合は、UICollectionViewCellアニメーションのさまざまな方法の非常に詳細な説明が含まれています。

2
RandomGuy

performBatchUpdates:completion:ブロック内のコレクションビュー全体をリロードすると、iOS 9シミュレーターでアニメーションが異常になります。特定のUICollectionViewCellを削除したい場合、またはインデックスパスがある場合は、そのブロックでdeleteItemsAtIndexPaths:を呼び出すことができます。 deleteItemsAtIndexPaths:を使用することにより、スムーズで素敵なアニメーションを作成します。

UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
    // or...
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];
2
nemesis

ヘルプテキストには次のように記載されています。

コレクションビュー内のすべてのアイテムを再ロードするには、このメソッドを呼び出します。これにより、コレクションビューは現在表示されているアイテムをすべて破棄し、再表示します。効率のために、コレクションビューには、表示されているセルと補助ビューのみが表示されます。再ロードの結果、コレクションデータが縮小した場合、コレクションビューはそれに応じてスクロールオフセットを調整します。アイテムが挿入または削除されるアニメーションブロックの途中でこのメソッドを呼び出さないでください。挿入と削除により、テーブルのデータが自動的に適切に更新されます。

重要な部分は、「コレクションビューで現在表示されているアイテムをすべて破棄する」ことだと思います。破棄されたアイテムの動きをどのようにアニメーション化するのですか?

1
Victor Engel