UICollectionViewでExcelライクなUIを作成する


# やりたいこと

* UICollectionViewでExcelライクなUIを作りたい
    * 一行目と一列目を固定させてスクロールさせたい
* ヘッダーはxibを使用する
    * ヘッダーのみ高さを変えたい

# コード

``` swift
import UIKit

class ViewController: UIViewController {

	@IBOutlet weak var gridCollectionView: UICollectionView! {
		didSet {
			gridCollectionView.bounces = false
		}
	}
    
    @IBOutlet weak var gridLayout: StickyGridCollectionViewLayout! {
        didSet {
			gridLayout.stickyRowsCount = 1
			gridLayout.stickyColumnsCount = 1
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let leftNib = UINib(nibName: "HeaderLeftCollectionViewCell", bundle: nil)
        gridCollectionView.register(leftNib, forCellWithReuseIdentifier: "HeaderLeftCollectionViewCell")
        let rightNib = UINib(nibName: "HeaderRightCollectionViewCell", bundle: nil)
        gridCollectionView.register(rightNib, forCellWithReuseIdentifier: "HeaderRightCollectionViewCell")
        
    }
    
}

// MARK: UICollectionViewDataSource

extension ViewController: UICollectionViewDataSource {

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

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        
        if indexPath.section == 0, indexPath.row == 0 {
            // ヘッダー（左）
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HeaderLeftCollectionViewCell", for: indexPath) as? HeaderLeftCollectionViewCell else {
                return UICollectionViewCell()
            }
            return cell
        } else if indexPath.section == 0, indexPath.row != 0 {
            // ヘッダー（右）
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HeaderRightCollectionViewCell", for: indexPath) as? HeaderRightCollectionViewCell else {
                return UICollectionViewCell()
            }
            return cell
        } else {
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as? CollectionViewCell else {
                return UICollectionViewCell()
            }
            cell.titleLabel.text = "\(indexPath)"
            cell.backgroundColor = gridLayout.isItemSticky(at: indexPath) ? .groupTableViewBackground : .white
            cell.layer.borderWidth = 0.5
            cell.layer.borderColor = UIColor.lightGray.cgColor
            return cell
        }
    }
}

// MARK: UICollectionViewDelegateFlowLayout

extension ViewController: UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = 100
        if indexPath.section == 0 {
            // ヘッダー
            return CGSize(width: width, height: 40)
        } else {
            return CGSize(width: width, height: 80)
        }
    }
}

```

# 実行結果

![UICollectionView.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420374/4615936e-f9bf-55f3-5eea-c598bc5e5cf8.gif)

# 参考
https://www.vadimbulavin.com/sticky-grid-collection-view/