LoginSignup
31
25

More than 5 years have passed since last update.

UITableViewを軽量化する!(Swift版)

Last updated at Posted at 2016-07-21

概要

UITableViewのUITableViewDataSourceを分離し、UIViewControllerを軽くする方法を共有します。

Obj-C版はこちら

下記のサイトを参考にさせて頂きました。
Objc.io

やること

・UITableViewDataSourceをUIViewContorlllerから分離する

やらないこと

・UITableViewCellのレイアウトについて
・UITableViewDelegateの分離について

実装手順

今回は、テキストを表示するだけのシンプルなTableViewでご説明します。

  1. TableViewに表示するデータを管理するクラスを作る
  2. UITableViewDataSouceの拡張クラスを作る
  3. UITableViewCellの拡張したクラスを作る
  4. 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
    }
}

完成イメージ

スクリーンショット 2015-12-02 22.56.15.png

まとめ

UITableViewDataSourceを分離でき、UIViewControllerの肥大化を防げました。

誤りや、もっとよい方法がございましたら、ご指摘頂ければ幸いです。

31
25
2

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
31
25