CollectionViewのcell表示に最低限必要なこと

# CollectionViewControllerのCell表示
CollectionViewやTableViewのcellの表示にいつも悩むので、色々試してまとめました。

## 試したパターン
1. StoryboardのCollectionViewControllerのなかにcell作る
2. xib作ってCollectionViewControllerで読み込み
3. xib作ってCustomCellで読み込み

## 大前提
以下三つの関数の設定

```swift
// MARK: UICollectionViewDataSource

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
        return cell
    }

```

それとCollectionViewControllerのクラスがきちんとStoryboardに紐づいていることなど



## 方法その1: CollectionViewControllerのCollectionView内にCell配置
**CollectionViewControllerのCollectionView内にCell配置** + **CellのreuseIdentifier設定**

一番簡単です

<img width="500" alt="スクリーンショット 2018-10-23 12.07.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/199256/8d3a0056-eca9-3ed3-9418-7d6285da75c8.png">


### 上のやり方のcellをカスタムクラスに紐付けるには
* CustomCellクラスを作成して、CellのCustomClassに設定
* 
CustomClassの名前はreuseIdentifierと異なっていても良い

<img width="500" alt="スクリーンショット 2018-10-23 12.17.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/199256/08ff6f79-9144-8a90-19aa-18c5efd0603a.png">


## 方法その2: xib + CollectionViewControllerでnib登録

**UINib(nibName:)でxib読み込み**(xibにreuseIdentifierの設定不要) +  **viewDidLoadでregister**

補足: ファイル名をreuseIdentifierと違うものにして、xibないのcellのreuseIdentifierを設定してもエラー


```swift

private let reuseIdentifier = "CollectionViewCell"

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let nib = UINib(nibName: "xibのファイル名(.xibいらない)", bundle: nil)
        collectionView!.register(nib, forCellWithReuseIdentifier: reuseIdentifier)
    }
```

これでとりあえずxib通り表示される


### 上のやり方のcellをカスタムクラスに紐付けるには
**UICollectionViewCellを継承したCustomクラスを作成** + **xibのcellのCustom Classに作成したCustomクラスを設定**

あとは普通にlabelなどxibからコードにつなぎこんで利用


## 方法その3: customのCollectionViewCellでxib読み込み

**UICollectionViewCellのxib作成** + **UICollectionViewCellのカスタムクラスを作成してxib読み込み** + **CollectionViewController側でcellの登録**

xibはCustomClassやFilesOwner等設定しなくてもいいです。

```swift

/// カスタムcell
class CollectionViewCell: UICollectionViewCell {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        // ここでxib読み込み xibの名前はCustomCellの名前と同じじゃなくても良い
        Bundle.main.loadNibNamed("TestCollectionViewCell", owner: self, options: nil)
    }
    
    // これがないとエラー
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        // fatalError("init(coder:) has not been implemented") // これでもよい
    }
}

```

```swift

private let reuseIdentifier = "CollectionViewCell"

    // CollectionViewController側
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView!.register(CollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
    }
```


### 上のやり方のcellをカスタムクラスに紐付けるには
* xib内のContentViewのCustom classを設定


<img width="438" alt="スクリーンショット 2018-10-23 10.49.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/199256/b5542bef-7b68-1dce-818d-9871538b6067.png">
 
* File's Ownerだけを設定しても、CustomCellクラスにlabelを紐付けできたのですが、なぜかawakeFromNibなどで変更できません。collection viewなどからの変更は可能でした。


# 終わりに
他に違ったやり方あれば教えてください

xibはジブと読むらしい