一つのUITableView内で要素があまり変わらない2つ以上のセルを使い分ける


iOSのメッセージアプリの吹き出しのようなセルのように、相手と自分かで異なるUITableViewCellを使いたいけど、中身の構成はあんまり変わらない場合の話を想定。

まず親UITableViewCellを一つ作る

xibファイル無しで、一つUITableViewCellを作り、全てのセルで共通のコンポーネントをプロパティで持っておく。

CommonTableViewCell.swift
import UIKit

class CommonTableViewCell: UITableViewCell {
    @IBOutlet weak var label: UILabel!
}

UITableViewCellを継承させて子UITableViewCellを必要な種類だけ準備する

ここではATableViewCellBTableViewCellを作る。
ATableViewCellにはUILabelUIButtonを置いておく。

UILabelの方は親であるCommonTableViewCelllabelと紐付ける。

UIButtonの方はATableViewCellのプロパティとして持っておく。

BTableViewCellにはUILabelだけ設置して、CommonTableViewCelllabelと紐付ける。

現時点で、CommonTableViewCelllabelにはATableViewCellBTableViewCell内のUILabelが紐付いていることになる。

使い方

まずはnibファイルを登録。

override func viewDidLoad() {
        super.viewDidLoad()

        var nib = UINib(nibName: "ATableViewCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: "ATableViewCell")
        nib = UINib(nibName: "BTableViewCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: "BTableViewCell")

        tableView.delegate = self
        tableView.dataSource = self
    }

tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)内では

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let row = indexPath.row
        var cell:CommonTableViewCell!
        // 乱数の3の剰余が0ならATableViewCellを使う
        if (rand() % 3 == 0){
            var aCell = tableView.dequeueReusableCellWithIdentifier("ATableViewCell") as ATableViewCell
            aCell.button.setTitle("Hoge", forState: UIControlState.Normal)
            cell = aCell
        } else {
            cell = tableView.dequeueReusableCellWithIdentifier("BTableViewCell") as BTableViewCell
        }
        cell.label.text = "\(row)"

        return cell
    }

などというように、継承の利点を活かして各値を設定できる。