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

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

##基本の考え方
1.中に表示するUITableViewCellは再利用する作りにする

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

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

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

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

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

##やりかた１.Storyboard内のTableView内でCellのプロトタイプを書いてしまう
###いいところ

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

###あんまよくないところ

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

###手順

1.ビューにUITableViewを設置する
<img width="300" alt="q1.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/2e6a9303-d224-80ee-c711-127b908ea9fe.png">

2.オブジェクトライブラリからTableViewCellをTableViewに貼り付ける
<img width="300" alt="q2.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/9f6ad860-accb-9dd6-b1f9-9cf2c50c15b7.png"><img width="300" alt="q3.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/06b5e90a-eb45-9399-c0e6-8961f28ad49e.png">

3.セルの高さを変えたり、なかに必要なオブジェクトを貼り付けてカスタマイズする
<img width="300" alt="q4.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/e06f9fe6-ce39-138b-9df7-3055023a563d.png">

4.レイアウトする
<img width="300" alt="q6.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/1bfa00c7-ffb2-1b56-1b83-e36603b7309f.png">

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

  + New FileでSwift fileを選択
  <img width="312" alt="q8.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/897806d4-0a1b-8222-c0fe-637dbafc102a.png">

  + セルのクラス名を入れる
  + クラスはUITableViewCellを継承して必要なパーツを宣言する

```swift: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で作ったクラス名にする
<img width="300" alt="q11.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/eaec11d3-af5d-4a8b-d3ef-10ea4a7fdd54.png">

7.Identifierに、呼び出すためのユニークな文字列を入れる
<img width="250" alt="q13.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/d29ba823-2cc6-b169-1d8b-158fa73770f4.png">

8.TableViewCellのところが自分で作ったクラスになるのでアウトレットを結ぶ
<img width="300" alt="q14.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/ebcd2ebf-f09d-5cdc-d015-829468cee0a1.png">

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

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

##やりかた２.XIBに別ファイルとして出してそれを使う
###いいところ
+ 他のビューでも同じようなセルを使いまわしたいときによい
+ xibとswiftがペアで格納できるので、ロジックを追いやすい

###あんまよくないところ
+ registerを忘れてできない！！ってハマることがある

###やり方

1.セルのXibを作る

+ New FileでViewをつくる。ファイル名をxibの名前にする
<img width="300" alt="q21.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/2d7a82e8-2ec0-4b22-fd20-f18b30dd8e7e.png"><img width="300" alt="q22.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/65b24646-5b9c-2ed4-aac8-ee541cd15602.png">

+ xibを表示してViewを選んで消す！
<img width="300" alt="q23.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/9125c569-fd47-a516-520f-11a127e7b95e.png">  <img width="300" alt="q24.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/4e3354c3-9fae-7030-dcbf-a288d68cfd7b.png">

+ オブジェクトライブラリからViewの代わりにTableViewCellを設置する
<img width="300" alt="q25.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/ea79c657-d15e-8d7a-6b42-45afd80f4efe.png">

+ 大きさを変えたり、必要なオブジェクトを貼り付ける
<img width="300" alt="q26.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/d8f418a1-79af-d83c-cc02-52d5b6ef5a3f.png">
2.セルのクラスを作成する
　やりかた1-5.と同じ。

3.1のXibでTableViewCellを選択してクラス名を2で作ったクラスにする
 <img width="300" alt="q27.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/7f319a15-b10d-fb68-0404-0253a28b36e1.png">

4.アウトレットを結ぶ
<img width="300" alt="q28.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/a8a62613-c41d-93ce-1627-0752de846d02.png">

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

```swift: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から呼び出せます

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


[Githubにソースをあげました](https://github.com/NaokoKubo/TableViewSample)