26
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[iOS]UITableViewで、reloadData完了を検知する ※注意:追記あり

Last updated at Posted at 2018-10-26

これまで

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です

Simulator Screen Shot - iPhone 8 Plus - 2018-10-26 at 16.15.15.png

更新を押しました

    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の中でやらないとマズイんじゃないですかね?
ひょっとしたら罠があるかもしれません。何か分かったら追記します。

別解

reloadData処理後に処理を行いたい

26
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?