【Swift】レイアウトやサイズが異なる複数のカスタムセルを並べる

# どういうことか

xibで作成した**レイアウトやサイズが異なる複数のカスタムセル**を並べて表示したい。

## コード全体像

```swift:ViewController
import UIKit

// CollectionViewのDelegateを使う
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    // StoryboardからCollectionViewを繋ぎこむ。セルは繋ぎこまなくてもよい
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.delegate = self
        collectionView.dataSource = self
        
        // カスタムセルのファイル名を指定
        let nib = UINib(nibName: "FirstCollectionViewCell", bundle: Bundle.main)
        let secondNib = UINib(nibName: "SecondCollectionViewCell", bundle: Bundle.main)
        
        // カスタムセルのIDを指定して登録
        collectionView.register(nib, forCellWithReuseIdentifier: "cardCell")
        collectionView.register(secondNib, forCellWithReuseIdentifier: "buttonsCell")
    }

    // セクションの数
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1
    }
    
    // カスタムセルの総数
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        // 各カスタムセルごとを順番（indexPath）で設定
        switch (indexPath.section) {

        // 順番ごとにIDを指定
        case 0:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cardCell", for: indexPath) as! CollectionViewCell
            
            // 例としてカスタムセルそのものに影と角丸をつける
            cell.layer.masksToBounds = false
            cell.layer.shadowColor = UIColor.black.cgColor
            cell.layer.shadowOpacity = 0.2
            cell.layer.shadowRadius = 4
            cell.layer.shadowOffset = CGSize(width: 2, height: 2)
            
            return cell

        case 1:
            // こちらのカスタムセルは単純に表示するだけ
            return collectionView.dequeueReusableCell(withReuseIdentifier: "buttonsCell", for: indexPath) as! CollectionViewCell2

        // 構造上defaultに来ることはないが書かないとエラーになる
        default:
            return UICollectionViewCell()
        }
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
    
    // カスタムセルのサイズ
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        return CGSize(width: view.frame.width - 32, height: 200)
    }
    
    // 各カスタムセル外枠の余白
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        
        return UIEdgeInsets(top: 16, left: 16, bottom: 0, right: 16)
    }
}

```

## サイズをそれぞれで設定する

上記の書き方だとセルの大きさは `CGSize(width: view.frame.width - 32, height: 200)` で統一されてしまう。
それぞれでサイズを指定する場合はカスタムセルを並べる部分を応用して書けばいい。

```swift:ViewController
    // ここを書き直す
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        // 順番ごとにサイズを指定する
        switch (indexPath.section) {
        case 0:
            return CGSize(width: view.frame.width - 80, height: 200)
            
        case 1:
            return CGSize(width: view.frame.width, height: 400)

        default:
            return CGSize(width: 0, height: 0)
        }
    }
```

以上です(´・ω・｀)