7

高さ 50 の 4 行のプレーンな UITableView があります。4 行目を押すと、UITableViewRowAnimationTop を使用して高さ 80 の 5 行目を挿入します。ここまでは順調ですね。

4行目をもう一度押したときに5行目を削除したい。しかし、UITableViewRowAnimationTop (またはその他のアニメーション スタイル) を使用して行を削除すると、アニメーションが非常にぎこちなくなります。アニメーションは開始されますが、アニメーションが完了する前にセルが突然消えます。(これは、背景色を持つセルを使用している場合にのみ明らかです。セルの下半分が、上のセルの下ではなく、突然消えることがわかります。)

コードは次のようなものです。

[self.tableview beginupdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[self.tableview endupdates];

行の高さはtableView:heightForRowAtIndexPath:メソッドによって提供されます。

この問題は、すべての行の高さが同じ場合、または削除される行が他の行よりも短い場合には発生しません。

回避策の 1 つは、削除する前に 5 番目のセルの高さを 50 に変更することだと思いますが、それはしたくありません。助けてください

4

3 に答える 3

1

UITableViewRowAnimationMiddle を使用すると、私にとっては少しひどいものになりました。

同様に、UITableViewRowAnimationTop を使用すると、テーブルビューのデフォルトのセルの高さを超える高さがアニメーションなしで表示/非表示になることに気付きました。したがって、テーブルビューの行の高さが 44 で、高さが 74 のセルでアニメーション化すると、すぐに30 が表示され、残りの 44 でアニメーション化されます。

UITableViewRowAnimationMiddle を使用すると、セルのコンテンツは適切にアニメーション化されますが、アニメーションの間、セルの境界線に不具合が生じます。最初は 30 で表示され、残りの 44 がアニメーション化されます。

于 2016-10-06T15:27:10.040 に答える
1

今朝、この問題に遭遇しました。基本的に、私はアニメーションを自分で処理し、アニメーションが完了したらセルを削除しました。これをどのように行ったかを示すコードを次に示します。

@property (nonatomic, strong) NSArray *tableData;
@property (nonatomic, strong) NSMutableDictionary *deletedItems;
...

- (void)deleteItemForCell:(UITableViewCell *)cell
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    NSObject *item = self.tableData[indexPath.row];

    NSNumber *rowKey = @(indexPath.row);

    __weak id weakSelf = self;
    [CATransaction setCompletionBlock:^{
        @synchronized(weakSelf) {
            [self.deletedItems removeObjectForKey:rowKey];
            [self.tableData removeObject:item];
            [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                                  withRowAnimation:UITableViewRowAnimationNone];
        }
    }];
    self.deletedItems[rowKey] = item;

    [self.tableView beginUpdates];
    [self.tableView endUpdates];

    [CATransaction commit];
}

- (CGFloat)tableView:(UITableView *)tableView
    heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.deletedItem[@(indexPath.row)]) {
        return 0;
    }
    return CELL_HEIGHT;
}

このコードは、データ構造内の削除された項目を追跡し、更新するようにテーブルに通知します。削除されたデータ構造内のアイテムは高さが 0 になり、「折りたたみ」アニメーションになります。

コードは CATransaction を使用して、アニメーションがいつ完了したかを認識します。完了すると、アイテムは tableData データ構造から削除され、アニメーションなしでテーブルから削除されます。

ノート:

  • 同期が必要かどうかはわかりませんが、アイテムを非同期的に削除することを扱っているため、同期が必要なようです。
  • ディクショナリのキーとして indexPath オブジェクトを使用しようとしましたが、うまくいかないようです。代わりに行を使用しました。

お役に立てれば。

于 2014-05-19T14:21:15.133 に答える
0

begin/endUpdates なしで試してみましたか? 一度奇妙なものを作るものを使ったことをぼんやりと覚えています。

次のreloadRowsAtIndexPaths:を試してみましたか? 1つあると仮定すると、つまり。

heightForRowdeleteRowsAt 呼び出しを行った時点で、応答に関してデータ ソースが正しく動作していると確信していますか? (たとえば、delete 呼び出しの後、物が見えなくなったことを示すフラグを設定すると、新しい行の高さが不適切になる可能性があります)

于 2013-01-02T08:25:23.147 に答える