6

セルの削除と挿入を同時に行うときに UITableView が提供するアニメーションに問題があります。私はセルのリストを持っています。それらを質問と呼びましょう。1 つの質問がタップされると、それ自体の下にセルが追加され、その質問に対する回答が表示されます。別の回答が既に表示されている場合は、その回答を表から削除する必要があります。この問題は、挿入されるセルが非常に高い場合に発生します。高さが非常に高いため、最終的な境界が削除されるセルが占めるスペースに侵入する場合、アニメーション中に、削除している回答セルを通して、追加されているセルを確認します。

(問題のビデオへのリンクを参照)

これは、私のコードがテーブルビューのセルを移動するように見えるものです

[tableView beginUpdates];

if (deleteIndex) {
    [tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
if (addIndex) {
[tableView insertRowsAtIndexPaths:@[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}

[tableView endUpdates];

私が試してみました

[tableView beginUpdates];

if (deleteIndex) {
    [tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];

//do stuff to update data source

[tableView beginUpdates];

if (addIndex) {
[tableView insertRowsAtIndexPaths:@[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}

[tableView endUpdates];

しかし、2 番目のブロックを開始する前にテーブル ビューが最初のセットの更新を完了したことを確認するコールバックがないため、ほとんど同じ問題が発生します。パフォームセレクターを遅延で使用できることはわかっていますが、これは応急処置のようです。

次に、このようなブロックにアニメーションを含めようとしました

[UIView animateWithDuration:0.0 animations:^{
    [tableView beginUpdates];

    if (deleteIndex) {
        [tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
    }
    [tableView endUpdates];

    //do stuff to update data source

} completion:^(BOOL finished) {

    [tableView beginUpdates];

    if (addIndex) {
        [tableView insertRowsAtIndexPaths:@[addIndex] withRowAnimation:UITableViewRowAnimationTop];
    }

    [tableView endUpdates];
}];

繰り返しますが、更新が実際に完了した後ではなく endUpdates を呼び出した後に完了ブロックが起動されるため、これは使用を解決しません。

また、ストーリーボードに移動して、セルに対してサブビューを境界にクリップすることが選択されていることを確認しました。繰り返しますが、セルのサブビューが予想される高さを超えて拡張されていないため、これで問題は解決しません。

アニメーションを遅くしてよく見ると、Apple がテーブル内で変更されないセルの下に追加するセルを挿入し、残りのセルを新しい位置に移動しているように見えます。その結果、削除されたセルは透明なウィンドウになり、内部で実際に何をしているかを確認できます。

4

2 に答える 2

2

正しいアプローチは、最初に古い回答を削除してから、アニメーションが終了した後に新しい回答を追加することです。セルのアニメーションが完了した後にトリガーされる UITableViewDelegate メソッドがあります。

tableView:didEndDisplayingCell:forRowAtIndexPath:

このデリゲート メソッド内に新しい回答行を挿入すると、正しいアニメーションになります。

覚えておくべき詳細がいくつかあります。正しいセルの高さが返され、セクション内の予想される正しい行数が返されるようにするためのロジックが必要です。これらのデータ ソース メソッドは、古い回答を削除した後に呼び出され、呼び出し時に新しい回答を追加するときに再度呼び出されます。

endUpdates

テーブルビューで

UITableViewRowAnimationTop 以外のものを使用すると、奇妙なアニメーション動作が発生します。これは、セルのコンテンツ ビューがアニメーション化されているものではないためです。

于 2013-06-14T00:58:58.170 に答える