設定画面をコードだけで書く時いつも悩む

# よくあるこんな設定画面

![スクリーンショット 2017-02-16 17.37.57.png](https://qiita-image-store.s3.amazonaws.com/0/50839/5cd24bf1-ac22-9582-b372-4cd440030e7f.png)

#　普通にかくとsectionとrowの番号指定・・・

```
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if section == 0 {
            return "ヘルプ"
        } else if section == 1 {
            return "設定"
        }
    }

```

せめて、defineして・・・とかも、いやだ。

# こんな感じで作ってみました

もっといいアプローチあったら教えてください！！

```
import UIKit

class ViewController: UIViewController {
    var tableView: UITableView!
    
    // セクションの情報を定義
    enum SectionMember: Int {
        case help, about, last
        var title: String? {
            let titles = ["ヘルプ", "設定", nil]
            return titles[self.rawValue]
        }
        var count: Int {
            let members = [AccountSectionMember.last.rawValue, SettingSectionMember.last.rawValue, 0]
            return members[self.rawValue]
        }
    }
    // セクションのメンバー情報を定義
    enum AccountSectionMember: Int {
        case account, timeline, push, privacy, payment, last
        var title: String? {
            let titles = ["アカウント", "タイムライン", "通知", "プライバシー", "お支払", nil]
            return titles[self.rawValue]
        }
    }
    enum SettingSectionMember: Int {
        case sound, data, about, last
        var title: String? {
            let titles = ["サウンド", "データ利用の設定", "アプリについて", nil]
            return titles[self.rawValue]
        }
    }
    // テーブルの情報をさくっととれるように
    struct TableInfo {
        var section: SectionMember
        var row: Int = 0
        
        init(inSection section: Int) {
            self.section = SectionMember(rawValue: section)!
        }
        init(indexPath: IndexPath) {
            self.init(inSection: indexPath.section)
            self.row = indexPath.row
        }
        
        func rowMemberTitle() -> String? {
            switch self.section {
            case .help:
                return AccountSectionMember(rawValue: row)?.title
            case .about:
                return SettingSectionMember(rawValue: row)?.title
            default:
                return nil
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        
        tableView = UITableView(frame: self.view.frame, style: .grouped)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.separatorStyle = .singleLine
        self.view.addSubview(tableView)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

extension ViewController: UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return SectionMember.last.rawValue
    }
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 35
    }
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 10
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 55
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return TableInfo(inSection: section).section.count
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return TableInfo(inSection: section).section.title
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier:"cell", for: indexPath as IndexPath)
        let tableInfo = TableInfo(indexPath: indexPath)
        // タイトルの取得
        cell.textLabel?.text = tableInfo.rowMemberTitle()!
        // 個別の処理はこんな感じ
        if tableInfo.section == .help && tableInfo.row == AccountSectionMember.account.rawValue {
            cell.accessoryType = .disclosureIndicator
        }
        return cell
    }
}

```