概要
UITableViewのUITableViewDataSourceを分離し、UIViewControllerを軽くする方法を共有します。
下記のサイトを参考にさせて頂きました。
Objc.io
やること
・UITableViewDataSourceをUIViewContorlllerから分離する
やらないこと
・UITableViewCellのレイアウトについて
・UITableViewDelegateの分離について
実装手順
今回は、テキストを表示するだけのシンプルなTableViewでご説明します。
- TableViewに表示するデータを管理するクラスを作る
- UITableViewDataSouceの拡張クラスを作る
- UITableViewCellの拡張したクラスを作る
- UIViewControllerから呼び出す
1. TableViewに表示するデータを管理するクラスを作る
Item.swift
import UIKit
class Item: NSObject {
var title = ""
init(title: String) {
self.title = title
}
}
2. UITableViewDataSouceの拡張クラスを作る
ItemDataSource.swift
import UIKit
typealias TableViewCellConfigureBlock = (cell: UITableViewCell, item: NSObject) -> Void
class ItemDataSource: NSObject {
var items = [NSObject]()
var cellIdentifier = ""
var configureCellBlock: TableViewCellConfigureBlock?
init(items: [Item], cellIdentifier: String, configureCellBlock: TableViewCellConfigureBlock) {
self.items = items
self.cellIdentifier = cellIdentifier
self.configureCellBlock = configureCellBlock
}
}
extension ItemDataSource: UITableViewDataSource {
//MARK: - UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier,
forIndexPath: indexPath)
if let configureCellBlock = self.configureCellBlock {
configureCellBlock(cell: cell, item: self.itemAtIndexPath(indexPath))
}
return cell
}
//MARK: - Private
private func itemAtIndexPath(indexPath: NSIndexPath) -> NSObject{
return items[indexPath.row]
}
}
3. UITableViewCellの拡張したクラスを作る
ItemCell.swift
import UIKit
class ItemCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
var item: Item? {
didSet {
if let item = item {
self.titleLabel.text = item.title
}
}
}
}
4. UIViewControllerから呼び出す
今回作ったItemDataSourceのインスタンスをUITableViewのdataSourceプロパティにセットするだけです。
ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var dataSource: ItemDataSource?
//MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
self.setup()
}
//MARK: - Private
private func setup() {
dataSource = ItemDataSource(items: [Item(title: "株式会社"),Item(title: "スマートデバイス"),Item(title: "テクノロジー")],
cellIdentifier: "ItemCell") { (cell, item) in
if let cell = cell as? ItemCell, let item = item as? Item {
cell.item = item
}
}
tableView.dataSource = dataSource
}
}
完成イメージ
まとめ
UITableViewDataSourceを分離でき、UIViewControllerの肥大化を防げました。
誤りや、もっとよい方法がございましたら、ご指摘頂ければ幸いです。