MILLEN BOX 2

個人iOSアプリ開発者hollymotoによる勉強の記録。時々雑記。

TableViewの複数の変更をアニメーション付きで反映させたい時はperformBatchUpdates(_:completion:)を使う

こんにちは。hollymoto@anthrgrnwrld です。
TableViewを表示した時や再表示した時に、いろんな変更や動作を一気にやりたい時があります。
が、それを単純にシーケンシャルに書いてしまうとうまくいかないことがあります。
今回の私の場合だとscrollToRowでTableの頭に戻ってから、先頭にinsertRowsするという動作が意図したアニメーションをしてくれない、もっと具体的にいうとscrollToRowで先頭に行くんだけど現在表示中のCellの真上にinsertRowsされちゃってRowが追加されたことのアニメーションが効果的に表示されなかったのです。
今回はそんなTableViewで複数処理を行った時の意図しない動きの解決方法についてです。

  • 失敗した時のコード
self.tableView.insertRows(at: [indexPath], with: .automatic)
self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)

上記コードだと変な動きしちゃうんですよ。
それで見つけたのがperformBatchUpdates(_:completion:)です。

https://developer.apple.com/documentation/uikit/uitableview/2887515-performbatchupdates

ここの中に

Use this method in cases where you want to make multiple changes to the table view in one single animated operation, as opposed to several separate animations.

とあります。私が求めていたものがここにありそうな気がしてきました。
このAPIを使って適応したコードが以下になります。

  • うまくいった時のコード
tableView.performBatchUpdates({
    self.tableView.insertRows(at: [indexPath], with: .automatic)
    self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
}, completion: nil)

現状これでうまく動いています。
TableViewって結構気を付けないと意図しない動作しないことがあるんですね。注意します。