LoginSignup
9
7

More than 5 years have passed since last update.

【iOS】アコーディオン(折りたたみ)式テーブルビューを作る!!

Last updated at Posted at 2017-11-26

こういうのがつくりたいとき

AccordionTableView.mov.gif

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

どうつくるか

ライブラリを使用して実装しました。
→ 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 のサンプルプロジェクトとか、readmeを読めば簡単に実装できると思います!
本投稿が理解の一助となれば幸いです!

9
7
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
9
7