Help us understand the problem. What is going on with this article?

TableViewのDataSourceとDelegateをViewControllerから分離

More than 1 year has passed since last update.

はじめに

  • tableViewを使う場合, datasourceとdelegateを使って、セルの設定やテーブルのデータを設定します.
  • その結果, 以下のような感じになりがち
ViewController.swift
import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
    }

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

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
        cell.textLabel?.text = String(indexPath.row)
        return cell
    }
}
  • 最低限のデリゲートのみしか書いてませんが、どんどん増やしていくと見づらいコードになりがちです。
  • そこで、これらのdelegateとdatasourceをViewControllerから分離しましょう!がこの記事でお伝えすることです.

実装

  • TableViewController.swiftTableViewDataSourceDelegateController.swiftの2つに分けました.
  • TableViewDataSourceDelegateController.swiftにdelegateとdatasourceを書いています.

  • tableviewはxibファイルで作成し, UIViewにサブビューとして追加しています.

  • tableviewcellもxibで作成しています.

TableViewController.swift
import UIKit

class TableViewController: UIViewController {


    let tableView = UINib(nibName: "TableView", bundle: nil).instantiate(withOwner: self, options: nil).first as! UITableView

    var tableViewDataSourceDelegate: TableViewDataSourceDelegateController = TableViewDataSourceDelegateController()


    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "tableViewCell")

        tableView.delegate = tableViewDataSourceDelegate
        tableView.dataSource = tableViewDataSourceDelegate

        self.view.addSubview(tableView)
    }


}
TableViewDataSourceDelegateController.swift
import UIKit

typealias UITableViewDD = UITableViewDelegate & UITableViewDataSource

class TableViewDataSourceDelegateController: UITableView, UITableViewDD {


    var tableData: [[String]] = [
        ["a", "b", "c"],
        ["d", "e"],
        ["f"],
        ["g", "h", "i", "j", "k"],
    ]


    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return nil
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 20
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return nil
    }
    func numberOfSections(in tableView: UITableView) -> Int { // sectionの数を決める
        return tableData.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableData[section].count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)

        cell.textLabel?.text = tableData[indexPath.section][indexPath.row]

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("didSelectRowAt: \(indexPath)")

        // タップ後すぐ非選択状態にするには下記メソッドを呼び出します.
        tableView.deselectRow(at: indexPath, animated: true)
    }

}

最後に

  • インターンで学んだことを思い出しながら書いています.
  • ViewControllerの肥大化を抑えられるのはありがたいです.
  • 記事作成にあたって, 作成したプロジェクトをGitHubにおいてあります. GitHubレポジトリ

参考

tableView delegate/dataSourceを別ファイルにする場合のコツ
swiftでDelegate/DataSourceを分離したいときに気をつけること

yodaaa
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away