8

デフォルトのFlowLayout、独自のセクションなど、すべての基本的なものでコレクションビューを作成しています。
私が正しく使用していると仮定するとcollectionView:CellForItemAtIndexPath:、他のすべてのdataSourceプロトコル

mainData、辞書の配列 (元のデータ) でありmainDataReferenceOrdered、(同じ要素が指している) と同じデータを含む他の配列です。順序付けられたデータへのコントローラーの現在の配列ポインターです。mainDataNameOrderedmainDataQuantiteOrderedmainData
dataToDisplay

並べ替えるときは、次のように、コレクション ビュー バッチでデータを変更するだけです。

[itemCollectionControl.collectionView performBatchUpdates:^{
        dataToDisplay = mainDataReferenceOrdered; //or any other ordered array
        [itemCollectionControl.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, itemCollectionControl.collectionView.numberOfSections)]];
    } completion:^(BOOL finished) {}];

ただし、コレクションは、既に表示されている場合や適切な場所にある場合でも、すべてのセルをフェードします。

UICollectionView に関する Apple のドキュメントを読みましたが、何を見逃したのかわかりません。私はそれについて他のスレッドも読みましたが、どうすればいいのかまだ探しています。

セルに適用するアニメーションを知るために、バッチは何を見ますか?


私の解決策

これは私が使用する最終的なコードであり、私が推測する iOS プログラミング ガイドラインに最も近いものです。

[itemCollectionControl.collectionView performBatchUpdates:^{
    NSArray *oldOrder = dataToDisplay;
    dataToDisplay = mainDataNBContainersOrdered;
    for (NSInteger i = 0; i < oldOrder.count; i++) {
        NSIndexPath *fromIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
        NSInteger j = [dataToDisplay indexOfObject:oldOrder[i]];
        NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:j inSection:0];
        [itemCollectionControl.collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
    }
} completion:^(BOOL finished) {
    if (finished) {
        [itemCollectionControl.collectionView reloadData];
    }
}];

古い注文アイテムをすべてブラウズし、それらの新しい位置を確認し、それを適用する-[UICollectionView moveItemAtIndexPath:toIndexPath:]
だけです 補完は iOS7 では役に立たないかもしれません。iOS6 シャッフルの最後に正しい順序を強制します。

編集

解決策を見つけたと思いますが、そのプロジェクトでテストすることはできなくなりました。おそらく、2 行のコードを追加するだけで、このひどい不具合が修正されるはずです。

の呼び出しの前に-[UICollectionView moveItemAtIndexPath:toIndexPath:]、呼び出し-[UICollectionView beginUpdates]、そして最後にすべての動きの後-[UICollectionView endUpdates]

テストできる人で動作することがわかった場合は、教えてください。

4

1 に答える 1

6

コレクション ビューは、データ モデル内のアイテムの ID を認識しないため、アイテムが移動したことを知る方法がありません。したがって、を使用してバッチ更新内で各セルが移動する場所をコレクション ビューに明示的に伝える必要がありますmoveItemAtIndexPath:toIndexPath:。from 配列内のアイテムをループし、to 配列内の位置を調べることで、これを自分で計算できます。このようなもの(記憶から入力したため、タイプミスについては申し訳ありません):

[itemCollectionControl.collectionView performBatchUpdates:^{
    for (NSInteger i = 0; i < mainDataReferenceOrdered.count; i++) {
        NSIndexPath *fromIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
        NSInteger j = [mainDataNameOrdered indexOfObject:mainDataReferenceOrdered[i]];
        NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:j inSection:0];
        [itemCollectionControl.collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
    }
} completion:^(BOOL finished) {}];

アイテムが大量 (数千) ある場合は、検索を高速化するためにセットの使用を検討することをお勧めします。

より一般的に適用可能なアプローチは、バッチ更新を計算できるTLIndexPathToolsのようなものを使用することです。Shuffle サンプル プロジェクトを見てください。

于 2013-10-23T03:28:18.000 に答える