Collection ViewのCustom Cellの作り方

# どんなものができる？
Collection ViewのCustom Cellを作ることができるようになれば、Spotifyの上の方のこういう部品を作れるようになります！
 ![Spotify例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/1a9a88e5-3ff0-381d-10e6-9d31f6787d70.jpeg)
この記事ではこれの再現を通してCustom Collection Viewの作り方を解説します！

## 1. StoryboardにColleciton Viewを配置する
Collection ViewをStoryboard上に配置し、
![1-1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/ed409314-eb16-fb96-8ab3-d8f3e811239c.png)
制約をつけます
今回は上と左右にSafeAreaに対する制約をつけて、高さを設定しました
![1-2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/c08b2c72-bab1-5959-d255-08130bcd8657.png)
今回はCustom Collection View Cellを自分で作るので、元々おいてあるCollection ViewCellを選択し、削除しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/4b34288e-cb05-0c59-1c74-838e8bd65c74.png)
こんな感じになっていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/de64a701-f170-0bab-21a1-06a027b0f897.png)

## 2. Custom Cell用のファイルを作成
メニューバーの File > New > File...を押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/4331f2e5-1c6c-232e-01bb-e3d8fc05fabc.png)
Cocoa Touch Classを選択して「Next」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/0cc946ee-f870-35cc-e9f0-72489a46d715.png)
Subclass of: を、「UICollectionViewCell」にして、
Class: にわかりやすい名前を入力します
今回は`CustomCell`という名前に設定しました
Also create XIB fileにチェックを付けて、「Next」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/5ad7aceb-90a0-5f3b-9dfb-97e2ccfa17ec.png)
すると、`CustomCell.swift`と、`CustomCell.xib`というファイルができるはずです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/ff0dc334-1a3e-9941-a273-0a0df2c392ae.png)

## 3. Custom Cellの見た目を設定する
`CustomCell.xib`を開きます
デフォルトだとCellの大きさが小さすぎて開発しづらいので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/11108b2a-5bfd-6bef-7ea5-9a3ef4cf4114.png)
テキトーに広げます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/69187da7-001c-7fe3-b413-9d50b9893bcc.png)
SpotifyのCellを観察してみると、
左側にアスペクト比1:1の画像、
右側に改行可能なラベル
が配置されてることがわかります
（ミセスまじで好き、、この記事もミセス聴きながら書いてました笑）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/95e33c44-b8b6-0eaa-77db-4109c3fe2adc.png)
Image Viewを
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/f0c2d42c-1696-7cd3-1ce0-9e2b4902ca0e.png)
Cellの上に配置し、
上下、左に距離の制約をつけ、
アスペクト比の制約をつけます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/4a1e9376-3dd2-851c-a136-d7d92ad6288a.png)
アスペクト比を1:1に設定し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/09e496fd-c8ea-e2e3-0e3b-65ce2a95654f.png)
これでImage Viewの配置は完了です

同じようにLabelも配置し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/18f7f1e2-a989-1705-978e-4dbdd211ccd8.png)
上下左右に制約をつけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/6dc984a9-113f-10df-63bf-4ca7e479c7cb.png)
改行可能にするためにLinesを0に設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/7c26aef1-b3a9-6844-fbba-eb9530147b21.png)

これでCustomViewの見た目の設定が完了しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/ab7b3eee-9d06-ff4f-59e4-2d296573996f.png)

## 4. Custom Cell Classを実装する
```swift
import UIKit

class CustomCell: UICollectionViewCell {
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var imageView: UIImageView!

    override func awakeFromNib() {
        super.awakeFromNib()
        
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        
        label.text = ""
        imageView.image = UIImage()
    }
    
    func setupCell(imageName: String, labelText: String) {
        label.text = labelText
        imageView.image = UIImage(named: imageName)
    }
    
}
```
やってること：

- `@IBOutlet`でUI部品の宣言をしています

- `awakeFromNib()`は、xibファイルが初めて読み込まれるときに１度だけ呼ばれるメソッドです
ViewControllerでいうところのviewDidLoadが近いと思います
今回は特に何も書いていません

- `prepareForReuse()`は、xibが再利用されるときに呼ばれるメソッドです
再利用については、[こちらの記事](https://qiita.com/takehilo/items/1145240bb3b72f7d0317)がわかりやすいので読んでみてください。
主に初期化を行います

- 最後に、`setupCell()`はCellをセットアップするためのメソッドです


ここまで書けたら、`CustomCell.xib`を開いて、関連づけをしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/78e523dd-75b9-43d1-ebf0-45c76e504a42.png)

## 5. ViewControllerを実装する
最後に、CustomCellを呼び出す側の実装です
```ViewController.swift
import UIKit

class ViewController: UIViewController, UICollectionViewDataSource {
    @IBOutlet var collectionView: UICollectionView!
    
    let playlists = [
        ["green_apple", "青りんごさん"],
        ["karaoke_kids", "子供に人気"],
        ["karaoke_otoshiyori", "お年寄りに人気"],
        ["musician", "今人気のミュージシャン"],
        ["official_hige", "公式髭男爵"]
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.dataSource = self
        collectionView.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "CustomCell")
        
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: collectionView.frame.width / 2 - 20 , height: 46)
        layout.sectionInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
        collectionView.collectionViewLayout = layout
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        playlists.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath)
        
        if let cell = cell as? CustomCell {
            cell.setupCell(imageName: playlists[indexPath.row][0], labelText: playlists[indexPath.row][1])
        }
        
        return cell
    }

}
```

主要な部分をそれぞれ解説していきます

--- 

まずViewDidLoad内のこれ

```swift
collectionView.dataSource = self
```

Collection ViewにはdataSourceというものがあって、こいつは、Collection View内のデータを管理するProtocolです。
Collection ViewをこのViewControllerで使うということを設定するために、dataSourceをselfに設定しています。


---
次はこの部分
```swift
collectionView.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "CustomCell")
```
Collection Viewで使用するセルを`register(_:forCellWithReuseIdentifier:)`メソッドで登録しています。
第一引数にはUINibオブジェクトを渡します。
UINibのイニシャライザに渡しているCustomCellという文字列は、セルのXIBファイル名と一致させます。
第二引数の`forCellWithReuseIdentifier`には、セルの再利用識別子というものを指定します。
ここの文字列は任意ですが、ここではCustomCellを指定します。

---


```swift
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: collectionView.frame.width / 2 - 20 , height: 46)
layout.sectionInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
collectionView.collectionViewLayout = layout
```

ここではCollection View Cellの大きさや隙間の大きさなどを設定しています。


---


```swift
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    playlists.count
}
```

このメソッドには、Collection View Cellを何個表示するのかを返します。

---

```swift
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath)
        
    if let cell = cell as? CustomCell {
        cell.setupCell(imageName: playlists[indexPath.row][0], labelText: playlists[indexPath.row][1])
    }
        
    return cell
}
```

この部分では、`dequeueReusableCell`でCustom Cellをとってきて、
Custom Cellの`setupCell`メソッドを呼び、cellを設定しています。

---
コードを書けたら、StoryBoardに移動し、`collectionView`を関連付けしましょう。

## 6. 完成
色や大きさを微調整すれば
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540178/80c7300c-fa7d-3c30-6058-874bd810e487.png)
こんな感じにできましたー！


今回のソースコードは↓ここにあります

https://github.com/sugijotaro/CustomCollectionViewExample


## 参考
https://developer.apple.com/documentation/uikit/uicollectionview

https://developer.apple.com/documentation/uikit/uicollectionviewcell

https://developer.apple.com/documentation/uikit/uicollectionviewdatasource

https://blog.mothule.com/ios/uitableview/ios-uitableview-uitableviewcell-customize

https://qiita.com/takehilo/items/1145240bb3b72f7d0317