【iOS】アコーディオン（折りたたみ）式テーブルビューを作る！！

##こういうのがつくりたいとき
![AccordionTableView.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/138735/f93978ac-92be-47e3-1ecb-af7c50c11bd9.gif)

・セルが折りたたまれるテーブルビュー
・セクションありのセルと、なしのセルがある


##どうつくるか
ライブラリを使用して実装しました。
→　[LUExpandableTableView](https://github.com/LaurentiuUngur/LUExpandableTableView)


##つくる

＜手順＞
1. ライブラリインストール（cocoapod, carthage,..）
2. LUExpandableTableViewクラスのtableView作成
4. セクション用のセル作成（LUExpandableTableViewSectionHeaderクラスを使用）
5. xib登録
6. デリゲート設定
7. デリゲートメソッドの実装

通常のtableViewを使用するときと同じです!
使用するtableViewのクラスをLUExpandableTableView,　セクション用のviewクラスをLUExpandableTableViewSectionHeaderにするだけ。
あとは好きなようにカスタムっ

###セクションありのセル、セクションなしのセルを設定したい！

・セクションなし
→　セクションの高さを0に設定。expand状態にする

``` ViewController.swift
func expandableTableView(_ expandableTableView: LUExpandableTableView, heightForHeaderInSection section: Int) -> CGFloat {
    
        if section == 0 || section == 3 {
            //　高さを0に
            return 0
        } else {
            return 69
        }
    }
```

``` ViewController.swift
override func viewDidLoad() {
        super.viewDidLoad()
        
        expandableTableView.register(MyTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        expandableTableView.register(UINib(nibName: "MyExpandableTableViewSectionHeader", bundle: Bundle.main), forHeaderFooterViewReuseIdentifier: sectionHeaderReuseIdentifier)
        
        expandableTableView.expandableTableViewDataSource = self
        expandableTableView.expandableTableViewDelegate = self
        
        // セクションいらないところは、開いた状態にしておく（引数はセクションの位置）
        expandableTableView.expandSections(at: [0])
        expandableTableView.expandSections(at: [3])
    }
```

###開いたり、閉じたりした時に何かしたい！

isExpandedの値をみて処理をすればOK

```MyExpandableTableViewSectionHeader.swift
//セクション用のviewクラス

final class MyExpandableTableViewSectionHeader: LUExpandableTableViewSectionHeader {
    // MARK: - Properties
    
    @IBOutlet weak var expandCollapseButton: UIButton!
    @IBOutlet weak var label: UILabel!
    
    override var isExpanded: Bool {
        didSet {
            // Change the title of the button when section header expand/collapse
            // 開いてたらボタンのテキストを「Collapse」 、　閉じてたら「Expand」
            expandCollapseButton?.setTitle(isExpanded ? "Collapse" : "Expand", for: .normal)
        }
    }

```

###セクションのタップイベント時に何かさせたい！

・開いたり、閉じたりをタップ時にさせたい
→　delegate?.expandableSectionHeader(self, shouldExpandOrCollapseAtSection: section)　を記述すればOK。

・タップ時の通知をViewControllerに送る
→　タップを検出できる要素をつくる
→　タップ検出タイミングで、delegate?.expandableSectionHeader(self, wasSelectedAtSection: section)　を呼べば、デリゲートメソッドの didSelectSectionHeader が呼ばれるので、そこでセクションタップ後にしたい処理を書く。


```MyExpandableTableViewSectionHeader.swift
final class MyExpandableTableViewSectionHeader: LUExpandableTableViewSectionHeader {
    // MARK: - Properties
    
    @IBOutlet weak var expandCollapseButton: UIButton!
    @IBOutlet weak var label: UILabel!
    
    override var isExpanded: Bool {
        didSet {
            // Change the title of the button when section header expand/collapse
            expandCollapseButton?.setTitle(isExpanded ? "Collapse" : "Expand", for: .normal)
        }
    }
    
    // MARK: - Base Class Overrides
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // ラベルをタップ検出可能にする
        label?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapOnLabel)))
        label?.isUserInteractionEnabled = true
    }
    
    // MARK: - IBActions
    
    @IBAction func expandCollapse(_ sender: UIButton) {
        // セクションの中にあるボタンタップで開いたり、閉じた
        // セクションの色を変えたりとかも！
        delegate?.expandableSectionHeader(self, shouldExpandOrCollapseAtSection: section)
    }
    
    // MARK: - Private Functions
    
    @objc private func didTapOnLabel(_ sender: UIGestureRecognizer) {
        // ラベルタップ時に選択された情報を通知する
        delegate?.expandableSectionHeader(self, wasSelectedAtSection: section)
    }
}

```

```ViewContoroller.swift
    func expandableTableView(_ expandableTableView: LUExpandableTableView, didSelectSectionHeader sectionHeader: LUExpandableTableViewSectionHeader, atSection section: Int) {
        //　ラベルがタップされた時にここがはしる
        //  セクション内のセルの色かえたりとかテキストを変えたり
        print("Did select section header at section \(section)")
    }

```

##おわり
[LUExpandableTableView](https://github.com/LaurentiuUngur/LUExpandableTableView)　のサンプルプロジェクトとか、readmeを読めば簡単に実装できると思います！
本投稿が理解の一助となれば幸いです！