5

のセクション間の変更をアニメーション化するのに問題がありますUICollectionView。プログラムがクラッシュし続けます。何が問題なのですか?

4 つのセクションを持つコレクション ビューがあります。

0: あ
1: ろ
2:し
3:し

同じアイテムを持つセクションが 3 つだけになるように変換したい:

0: あ
1: ろ、し
2: だ

そして、この変換をアニメーション化したいと思います:

// Initial state

NSArray *source = @[ @[@"A"], @[@"B"], @[@"C"], @[@"D"] ];


// Some data source methods

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [source[section] count];
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return [source count];
}


// Transformation: that works but I have to keep an empty section

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"], @[] ];

[collection performBatchUpdates:^{
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]
                        toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:3]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]];
} completion:nil];


// Transformation: that crashes!

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"] ];

[collection performBatchUpdates:^{
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]
                        toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]];
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:3]
                        toIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]];
    [collection deleteSections:[NSIndexSet indexSetWithIndex:3]];
} completion:nil];

内部アサーション エラー: Assertion failure in -[UICollectionView _endItemAnimations]...、またはさらに奇妙な malloc エラー: のいずれかで、クラッシュが発生し続けますincorrect checksum for freed object...

私が呼ばなければ、deleteSections:それも機能しません。私が最初に入れても、何も変わりません。ソースと宛先が同じものを削除しmoveItemAtIndexPath:toIndexPath:ても、何も変わりません。バッチ ブロックで実行しないと、明らかに最初のコマンドでクラッシュします。私は何かを見落としましたか?

4

2 に答える 2

1

UICollectionView に関するこの非常に興味深い記事からの抜粋:

バッチ更新ブロック内に新しいセクションを挿入する場合、そのセクションに項目を挿入してはなりません。これは暗黙的に処理されます。実際、バッチ更新ブロックで新しく挿入されたセクションにアイテムを挿入すると、コレクション ビューのレイヤー階層にスタックする「ゴースト」レイヤーが作成されます。この動作は文書化されておらず、例外がスローされないため、おそらくこれは UICollectionView の単なるバグです。

これを知っていると、セクションの削除とmoveItemFromIndexPath:toIndexPath連携がうまくいかないことはまったく驚くことではありません。「同じバグ」だと思います。

私が使用した解決策:

削除したはずのセクションに偽の非表示セルを挿入しました。これにより、私がmoveItemFromIndexPath:toIndexPath:. もちろん、それに応じてデータソースを調整しました!

于 2014-02-03T16:03:45.670 に答える
0

次のようなことを試しましたか:

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"] ];

[collection performBatchUpdates:^{
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]
                        toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]];
    [collection deleteSections:[NSIndexSet indexSetWithIndex:2]];
} completion:nil];
于 2013-05-24T14:13:03.900 に答える