iOS10 の UITableViewの高さが変わった時のアニメーションについて

# はじめに
こんにちは
タップするなど、高さがアニメーションして変わるTableViewが
iOS 9以前 と iOS 10.0 で動きが少し異なってしまい、調べていたら見つけたので
まとめてみたいと思います。
至らぬ点など多々あると思いますが、コメントなど頂けたら幸いです。

#デモ

## 実行時(iOS 9以前)
![7-3-1.gif](https://qiita-image-store.s3.amazonaws.com/0/128250/fad611b4-ba31-40ea-1d35-66a130cf1e58.gif)

## 実行時(iOS 10)
![8.gif](https://qiita-image-store.s3.amazonaws.com/0/128250/c3efebc0-5dea-454f-6003-ee884c3d077e.gif)

(見づらくてごめんなさい...)
iOS 10だと高さを変えた時にセル同士のラベルが重なっているように見えてしまいます。
# TableViewをreloadするタイミングでアニメーションを設定すると良い？
アニメーションして高さが変わるTableViewのセルをリロードする時は

```swift
tableView.reloadData()
```
ではなく

```swift
tableView.beginUpdates()
//データを変更する処理など
tableView.endUpdates()
```
とメソッドで挟むように記述します。そのTableViewに乗っているCellを  

```CustomTableViewCell.swift
override func layoutSubviews() {
    super.layoutSubviews()
    if #available(iOS 10, *) {
        UIView.animate(withDuration: 0.3) { self.contentView.layoutIfNeeded() }
    }
}
```
のようにアニメーションを設定するとiOS 9以前の動きにできるみたいです。

# もう1つの方法とその違い
また、以下のように設定する方法もあるみたいです。  

```swift
UIView.animate(withDuration: 0.3) {
    self.tableView.beginUpdates()
    //セルのデータを変更する処理など
    self.tableView.endUpdates()
    cell.layoutIfNeeded()
}
```

## 実行時(iOS 10)(わかりやすく色を付けてみました)
![color.gif](https://qiita-image-store.s3.amazonaws.com/0/128250/ba11d1f3-20a4-d2ba-3b9d-54df332fdf1e.gif)

この記述だとセルが小さく戻る時に、
他のセルの上を股がるようにアニメーションしてしまいます。
(緑・茶色のセルが画面に表示される際に水色の下から順に表示されるようなアニメーション)

# サンプルコード
一応gifのコードを貼っておきたいと思います。

```CustomTableViewCell.swift
import UIKit

class CustomTableViewCell: UITableViewCell {
    @IBOutlet weak var label: UILabel!
    
    var isOpen = false
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        if #available(iOS 10, *) {
            UIView.animate(withDuration: 0.3) { self.contentView.layoutIfNeeded() }
        }
    }
}
```

```MainViewController.swift
import UIKit

class MainViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    
    var cellTexts = ["AAA","BBB","CCC","DDD","EEE"]
    var openHeights: [CGFloat] = [308,132,132,132,132]
    var colors: [UIColor] = [UIColor.red,UIColor.blue,UIColor.cyan,UIColor.green,UIColor.brown]
    var isOpens = [false,false,false,false,false]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        let nib = UINib(nibName: "CustomTableViewCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "CustomTableViewCell")
    }
}

extension MainViewController: UITableViewDataSource {
    //テーブルの行ごとのセルを返却するメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for:indexPath) as! CustomTableViewCell
        cell.selectionStyle = .none
        cell.label.text = cellTexts[indexPath.row]
        cell.isOpen = isOpens[indexPath.row]
        cell.backgroundColor = colors[indexPath.row]
        return cell
    }
    
    //テーブルの行数を返却するメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cellTexts.count
    }
}

extension MainViewController: UITableViewDelegate {
    //セルを選択した時の処理
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath) as! CustomTableViewCell
        UIView.animate(withDuration: 0.3) {
            self.tableView.beginUpdates()
            if cell.isOpen{
                cell.isOpen = false
                self.isOpens[indexPath.row] = false
            }else{
                cell.isOpen = true
                self.isOpens[indexPath.row] = true
            }
            self.tableView.endUpdates()
            cell.layoutIfNeeded()
        }
        
    }
    
    // テーブルセルの高さを返します
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return isOpens[indexPath.row] ? openHeights[indexPath.row] : 44
    }
}

```
# 参考にさせていただいたページ
このiOS 10のUITableViewのアニメーションについて
>[スタック・オーバーフロー](http://stackoverflow.com/questions/39104846/uitableviewcell-animate-height-issue-in-ios-10/)

アニメーションするUITableViewについて
> [しめ鯖日記](http://llcc.hatenablog.com/entry/2015/07/24/235808) さん

バージョンチェックについて
> [不満足こそが、極上を生む。](http://blog.kitoko552.com/entry/2015/09/01/121949)さん

見て頂いてありがとうございます。