これまで
tableview.reloadData()
としたとき、内部的にわずかですがreloadData完了に時間がかかります。
なので
tableView.reloadData()
//reloadData()後を前提とした処理
とやってしまうと意図しない動作になります。
特にcellForRowAtIndexPathが呼ばれる前に処理すると最悪クラッシュしたりします。
それで今までは
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// indexPathが、tableView.indexPathsForVisibleRowsの最後のセルなら読み込み完了とする
}
などとすることがありました。
これはUITableViewのライフサイクル的に
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
// ↓
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
// ↓
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath)
という流れだからですが、この方法にも問題があるようです。
(問題の内容については割愛)
iOS11から
tableView.performBatchUpdates({
self.tableView.reloadData()
}) { (finished) in
print("reload完了しました🙂")
}
こういう書き方ができるようです。
これはそもそもセルの挿入、移動、削除などを1回のアニメーションで行うためのメソッドです。
個人的にあまり馴染みがないメソッドなのですが、それもそのはずで、UITableViewに導入されたのはiOS11からで、元はUICollectionViewにあったもののようです。
公式
https://developer.apple.com/documentation/uikit/uitableview/2887515-performbatchupdates
https://developer.apple.com/documentation/uikit/uicollectionview/1618045-performbatchupdates
まあ何はともあれ、簡単にreloadData()終了を検知できるのは非常にありがたいです。
しかしUITableViewはiOS11からなので注意が必要です。
(UICollectionViewはiOS6からですが)
実際に使ってみる
普通のUITableViewです
更新を押しました
didEndDisplaying section:2 row:3
didEndDisplaying section:2 row:2
didEndDisplaying section:2 row:1
didEndDisplaying section:2 row:0
didEndDisplaying section:1 row:3
didEndDisplaying section:1 row:2
didEndDisplaying section:1 row:1
didEndDisplaying section:1 row:0
cellForRowAt section:0 row:3
willDisplay section:0 row:3
cellForRowAt section:1 row:0
willDisplay section:1 row:0
cellForRowAt section:1 row:1
willDisplay section:1 row:1
cellForRowAt section:1 row:2
willDisplay section:1 row:2
cellForRowAt section:1 row:3
willDisplay section:1 row:3
cellForRowAt section:2 row:0
willDisplay section:2 row:0
cellForRowAt section:2 row:1
willDisplay section:2 row:1
cellForRowAt section:2 row:2
willDisplay section:2 row:2
cellForRowAt section:2 row:3
willDisplay section:2 row:3
cellForRowAt section:3 row:0
willDisplay section:3 row:0
cellForRowAt section:3 row:1
willDisplay section:3 row:1
cellForRowAt section:3 row:2
willDisplay section:3 row:2
cellForRowAt section:3 row:3
willDisplay section:3 row:3
didEndDisplaying section:3 row:0
didEndDisplaying section:3 row:1
didEndDisplaying section:3 row:2
didEndDisplaying section:3 row:3
didEndDisplaying section:0 row:3
didEndDisplaying section:1 row:0
didEndDisplaying section:1 row:0
reload完了しました🙂
追記:??動かないパターンが有る?? 🤔
これはUICollectionViewの方ですが、動いた!って言う人と動かないって言う人がいますね
https://stackoverflow.com/questions/14020027/how-do-i-know-that-the-uicollectionview-has-been-loaded-completely
そもそもreloadってUpdatesの中でやらないとマズイんじゃないですかね?
ひょっとしたら罠があるかもしれません。何か分かったら追記します。