LoginSignup
72
67

More than 3 years have passed since last update.

アコーディオンメニューを実装する

Last updated at Posted at 2015-10-29

 やっはろー。セクションごとに開閉できるテーブルビュー、いわゆるアコーディオンメニューを実装したい、という話をします。

346 Production

開閉する

 セクションの開閉とは要するにセル数の増減のことなのでそのようにします。

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if openedSections.contains(section) {
        return items[section].members.count
    } else {
        return 0
    }
}

タップする

 タップを検知するためにセクションのヘッダにジェスチャを貼ります。タグにセクションの番号を入れるとタップしたセクションがすぐにわかって便利。

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UITableViewHeaderFooterView()
    let gesture = UITapGestureRecognizer(target: self, action: #selector(sectionHeaderDidTap(_:)))
    view.addGestureRecognizer(gesture)
    view.tag = section
    return view
}
@objc func sectionHeaderDidTap(_ sender: UIGestureRecognizer) {
    if let section = sender.view?.tag {
        ...
    }
}

サンプルコード

 Playground で動くやつです。

import UIKit
import PlaygroundSupport

class ViewController: UITableViewController {
    private let items = [
        (type: "キュート", members: ["双葉", "緒方", "三村", "前川", "島村"]),
        (type: "クール", members: ["神崎", "多田", "アナ", "新田", "渋谷"]),
        (type: "パッション", members: ["諸星", "城ヶ崎", "赤城", "本田"]),
        (type: "ミシロ", members: ["美城"]),
    ]

    private var openedSections = Set<Int>()

    @objc func sectionHeaderDidTap(_ sender: UIGestureRecognizer) {
        if let section = sender.view?.tag {
            if openedSections.contains(section) {
                openedSections.remove(section)
            } else {
                openedSections.insert(section)
            }

            tableView.reloadSections(IndexSet(integer: section), with: .fade)
        }
    }

    // MARK: Table view data source

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = items[indexPath.section].members[indexPath.row]

        return cell
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if openedSections.contains(section) {
            return items[section].members.count
        } else {
            return 0
        }
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return items.count
    }

    // MARK: Table view delegate

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return items[section].type
    }

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UITableViewHeaderFooterView()
        let gesture = UITapGestureRecognizer(target: self, action: #selector(sectionHeaderDidTap(_:)))
        view.addGestureRecognizer(gesture)
        view.tag = section
        return view
    }
}

PlaygroundPage.current.liveView = ViewController()

楽しい!₍₍ (ง╹◡╹)ว ⁾⁾

72
67
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
72
67