9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TableViewのDataSourceとDelegateをViewControllerから分離

Last updated at Posted at 2019-01-07

はじめに

  • 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を分離したいときに気をつけること

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?