・セルが折りたたまれるテーブルビュー
・セクションありのセルと、なしのセルがある
##どうつくるか
ライブラリを使用して実装しました。
→ LUExpandableTableView
##つくる
<手順>
- ライブラリインストール(cocoapod, carthage,..)
- LUExpandableTableViewクラスのtableView作成
- セクション用のセル作成(LUExpandableTableViewSectionHeaderクラスを使用)
- xib登録
- デリゲート設定
- デリゲートメソッドの実装
通常のtableViewを使用するときと同じです!
使用するtableViewのクラスをLUExpandableTableView, セクション用のviewクラスをLUExpandableTableViewSectionHeaderにするだけ。
あとは好きなようにカスタムっ
###セクションありのセル、セクションなしのセルを設定したい!
・セクションなし
→ セクションの高さを0に設定。expand状態にする
func expandableTableView(_ expandableTableView: LUExpandableTableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 || section == 3 {
// 高さを0に
return 0
} else {
return 69
}
}
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
//セクション用の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 が呼ばれるので、そこでセクションタップ後にしたい処理を書く。
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)
}
}
func expandableTableView(_ expandableTableView: LUExpandableTableView, didSelectSectionHeader sectionHeader: LUExpandableTableViewSectionHeader, atSection section: Int) {
// ラベルがタップされた時にここがはしる
// セクション内のセルの色かえたりとかテキストを変えたり
print("Did select section header at section \(section)")
}
##おわり
LUExpandableTableView のサンプルプロジェクトとか、readmeを読めば簡単に実装できると思います!
本投稿が理解の一助となれば幸いです!