なすびのブログ

iOS・swiftの情報を気ままに書いていきます。

【Swift4.2】UITableViewをシンプルに管理する

はじめに

UITableViewで表示パターンが増えてセルの表示設定がカオスになった経験はありませんか? 僕は以前複数パターンのセル表示をしたときに、メソッドの中がぐちゃぐちゃになり絶望していました(笑) 今回はその時に考えたEnumを使ってシンプルに管理する方法を紹介します。

この方法は下図にある入力フォームのような表示項目が動的に変わらないかつ、セル内の要素がある程度似ている場合のUITableView向けです。

f:id:nasubiblog:20181217223837p:plain

ストーリーボードでセルを作成する

今回は2パターンのセルを作成しています。 セルのidentifierはそれぞれ"StandardCell"、"PeriodCell"としています。

f:id:nasubiblog:20181217223939p:plain

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に項目を追加するだけでいいので改修もしやすくなるのかなーと思います。

ただこのやり方だと動的にセルを追加する場合には対応できないので、それについては別途考えたいと思います。

たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 10 Swift 4.2対応

たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 10 Swift 4.2対応