カスタムTableViewCellを作るときにはだいたいこうやってます-プロトタイプで作るか、xibで作るか

きっかけ

仕事で他の人のソースをみることはよくありますが、最近UITableViewでセルの再利用をしていないソースを3回みました。
え?まじ??いいの???私老人会なのかしらって思いました。
iPhoneもだいぶハードが進化していろんなむちゃぶりされても動くようにはなってきたのですが、ちゃんとかいたほうがぬるぬる綺麗にうごくんじゃない?って思うんです。それで、まとめることにしました。
そういえば、cellForRowAtでcellの中身を全部removefromSuperviewしてから、addSubviewするというコードも1年ぐらい前に見たことがあります。
xib絶対使わない派の人もいるとは思いますが、楽したいなら使っちゃいましょう。

基本の考え方

1.中に表示するUITableViewCellは再利用する作りにする

  • TableViewにregisterして、使うときにはdequeueReusableCellを使って再利用する

2.cellForRowAt でセルを生成するときの処理は、極力最小になるように努力する

  • CALayerを使った角丸の処理は遅い
  • 画像をネット経由で読み込む場合には非同期に読み込む

3.heightForRowAtも頻繁に呼ばれるので注意する

  • cellの高さの計算が必要なら、cellそのものを使うのではなく、計算用の別クラスを使う

やりかた1.Storyboard内のTableView内でCellのプロトタイプを書いてしまう

いいところ

  • registerしなくてもいい
  • ファイルが増えないのでプロジェクトがスッキリする

あんまよくないところ

  • 他の画面でも同じセルを使い回すときにめんどうかもしれない

手順

1.ビューにUITableViewを設置する
q1.png

2.オブジェクトライブラリからTableViewCellをTableViewに貼り付ける
q2.pngq3.png

3.セルの高さを変えたり、なかに必要なオブジェクトを貼り付けてカスタマイズする
q4.png

4.レイアウトする
q6.png

5.セルのクラスを作成する

  • New FileでSwift fileを選択
    q8.png

  • セルのクラス名を入れる

  • クラスはUITableViewCellを継承して必要なパーツを宣言する

SampleCell1.swift
import UIKit

class SampleCell1:UITableViewCell {

    @IBOutlet weak var sampleImageView: UIImageView!
    @IBOutlet weak var sampleLabel:UILabel!
    @IBOutlet weak var sampleSwitch:UISwitch!
    @IBOutlet weak var sampleIndicator:UIActivityIndicatorView!

}}

6.Storyboardに戻ってTableViewCellを選択してクラス名を5で作ったクラス名にする
q11.png

7.Identifierに、呼び出すためのユニークな文字列を入れる
q13.png

8.TableViewCellのところが自分で作ったクラスになるのでアウトレットを結ぶ
q14.png

9.TableViewで直接プロトタイピングしているので7でつけた名前でそのままViewControllerから呼び出せます

ViewController.swift
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SampleCell1") as! SampleCell1

        return cell
    }

やりかた2.XIBに別ファイルとして出してそれを使う

いいところ

  • 他のビューでも同じようなセルを使いまわしたいときによい
  • xibとswiftがペアで格納できるので、ロジックを追いやすい

あんまよくないところ

  • registerを忘れてできない!!ってハマることがある

やり方

1.セルのXibを作る

  • New FileでViewをつくる。ファイル名をxibの名前にする
    q21.pngq22.png

  • xibを表示してViewを選んで消す!
    q23.png q24.png

  • オブジェクトライブラリからViewの代わりにTableViewCellを設置する
    q25.png

  • 大きさを変えたり、必要なオブジェクトを貼り付ける
    q26.png
    2.セルのクラスを作成する
     やりかた1-5.と同じ。

3.1のXibでTableViewCellを選択してクラス名を2で作ったクラスにする
q27.png

4.アウトレットを結ぶ
q28.png

5.ViewControllerのviewDidLoadで作ったクラスのレジストレーションをする
今回はUIViewにUITableViewを貼り付けたのでOutletで結んでself.tableViewとなっています。
あとidentifierは定数にしましょう

ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.tableView.register(UINib(nibName: "SampleCell2", bundle: nil), forCellReuseIdentifier: "SampleCell2")
    }

6.あとはそのままViewControllerから呼び出せます

ViewController.swift
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SampleCell2") as! SampleCell2

        return cell
    }

Githubにソースをあげました