はじめに
UITableViewで表示パターンが増えてセルの表示設定がカオスになった経験はありませんか?
僕は以前複数パターンのセル表示をしたときに、メソッドの中がぐちゃぐちゃになり絶望していました(笑)
今回はその時に考えたEnumを使ってシンプルに管理する方法を紹介します。
この方法は下図にある入力フォームのような表示項目が動的に変わらないかつ、セル内の要素がある程度似ている場合のUITableView向けです。
ストーリーボードでセルを作成する
今回は2パターンのセルを作成しています。
セルのidentifierはそれぞれ"StandardCell"、"PeriodCell"としています。
Enumで表示するセルを定義する
表示するセル毎にEnumを定義します。
例ではユーザー名、パスワード、何かの期間を入力するセルを定義しています。
表示するセルのidentifierとタイトルをEnumから取得できるように定義します。
enum DisplayCellType: Int, CaseIterable {
case userID
case password
case period
var identifier: String {
switch self {
case .userID, .password:
return "StandardCell"
case .period:
return "PeriodCell"
}
}
var title: String {
switch self {
case .userID:
return "ユーザーID"
case .password:
return "パスワード"
case .period:
return "何かの期間"
}
}
}
セルのパターン毎にクラスを作成する
ViewControllerから使う時にどのクラスのセルか判定したくないのでインターフェースを定義しておきます。
protocol CustomCell {
func setItem(_ title: String)
}
final class StandardCell: UITableViewCell, CustomCell {
@IBOutlet weak var titleLabel: UILabel!
func setItem(_ title: String) {
self.titleLabel.text = title
}
}
final class PeriodCell: UITableViewCell, CustomCell {
@IBOutlet weak var titleLabel: UILabel!
func setItem(_ title: String) {
self.titleLabel.text = title
}
}
ViewControllerからセルの設定を行う
あとはViewControllerからセルを利用します。
DisplayCellTypeはCaseIterableを継承しているのでallCasesでEnumの個数を返してやります。
セルのidentifierとタイトルはEnumから引っ張ってきて設定します。
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return DisplayCellType.allCases.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellType = DisplayCellType(rawValue: indexPath.row)!
let cell = tableView.dequeueReusableCell(withIdentifier: cellType.identifier) as! CustomCell & UITableViewCell
cell.setItem(cellType.title)
return cell
}
}
最後に
今回のようにEnumを使いセルの情報をEnumで定義してあげればViewControllerがシンプルになります。
またセルに表示する項目が増えた場合もViewContollerを触る必要なくEnumに項目を追加するだけでいいので改修もしやすくなるのかなーと思います。
ただこのやり方だと動的にセルを追加する場合には対応できないので、それについては別途考えたいと思います。