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


## これまで

tableview.reloadData()
としたとき、内部的にわずかですがreloadData完了に時間がかかります。
なので

```swift
tableView.reloadData()
//reloadData()後を前提とした処理
```

とやってしまうと意図しない動作になります。
特にcellForRowAtIndexPathが呼ばれる前に処理すると最悪クラッシュしたりします。

それで今までは

```swift
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // indexPathが、tableView.indexPathsForVisibleRowsの最後のセルなら読み込み完了とする
}

```
などとすることがありました。
これはUITableViewのライフサイクル的に

```swift

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から

```swift
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](https://qiita-image-store.s3.amazonaws.com/0/20784/4896173e-ea7a-6b0c-2c96-f3ae7f8610c8.png)

更新を押しました

```swift
    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処理後に処理を行いたい
](https://qiita.com/ponkichi4/items/d5d46556773a6bc98f9c)