私のプロジェクトでは、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のサブクラス化にはあまり興味がなかったので、どんな助けも素晴らしいでしょう...
ありがとう、ビル。
reloadDataはアニメーション化せず、UIViewアニメーションブロックに配置された場合も確実にアニメーション化しません。 UICollecitonView performBatchUpdatesブロックに入れたいので、次のようなものを試してください。
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {}];
-reloadData
に-performBatchUpdates:
をラップすると、1セクションのコレクションビューがアニメーション化されないようです。
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:nil];
ただし、このコードは機能します。
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
これは私がすべてのセクションのリロードをアニメーション化するためにしたことです:
[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)
Swiftユーザーの場合、コレクションビューにセクションが1つしかない場合:
self.collectionView.performBatchUpdates({
let indexSet = IndexSet(integersIn: 0...0)
self.collectionView.reloadSections(indexSet)
}, completion: nil)
より詳細な制御とカスタマイズ可能な機能チェック this が必要な場合は、UICollectionViewCellアニメーションのさまざまな方法の非常に詳細な説明が含まれています。
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];
ヘルプテキストには次のように記載されています。
コレクションビュー内のすべてのアイテムを再ロードするには、このメソッドを呼び出します。これにより、コレクションビューは現在表示されているアイテムをすべて破棄し、再表示します。効率のために、コレクションビューには、表示されているセルと補助ビューのみが表示されます。再ロードの結果、コレクションデータが縮小した場合、コレクションビューはそれに応じてスクロールオフセットを調整します。アイテムが挿入または削除されるアニメーションブロックの途中でこのメソッドを呼び出さないでください。挿入と削除により、テーブルのデータが自動的に適切に更新されます。
重要な部分は、「コレクションビューで現在表示されているアイテムをすべて破棄する」ことだと思います。破棄されたアイテムの動きをどのようにアニメーション化するのですか?