SnapchatやInstagramみたいなCollectionViewをライブラリ化しました！

# SnapLikeCollectionView
https://github.com/kboy-silvergym/SnapLikeCollectionView

<img width="875" alt="スクリーンショット 2018-12-03 23.48.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/5b337ca4-a17c-3b2e-b1fb-e69b9adca950.png">

# どんなライブラリ？

僕の務めるGraffity Inc.ではARKitを使ったアプリを多く作っているため、いつもカメラUIを作っています。

そしたら自ずと、InstagramとかSnapchatみたいなCollectionViewを作るわけですよ。

今作っているアプリで、もう３回目くらいなので、いい加減ライブラリ化しました。なんどもコピペするのは時間の無駄だし、完璧なコードではないですが、需要ありそうだと思うからです。

# InstagramやSnapchatとの比較

|作ったやつ|Instagram|Snapchat|
|:-:|:-:|:-:|
|<img src="https://github.com/kboy-silvergym/SnapLikeCollectionView/raw/master/Images/this.gif" width=150>|<img src="https://github.com/kboy-silvergym/SnapLikeCollectionView/raw/master/Images/instagram.gif" width=140>|<img src="https://github.com/kboy-silvergym/SnapLikeCollectionView/raw/master/Images/snapchat.gif" width=140>|

Cellを好きなようにカスタマイズすることで、InstagramのようにテキストのCellにも、Snapchatのように画像のCellにもできます。

# インストール方法

Cocoapodsだけ用意しました。

Podfileに以下を追加して`pod install`

```ruby
pod 'SnapLikeCollectionView'
```

# 使い方

## Cellを準備

Cellは`UICollectionViewCell`を継承して`SnapLikeCell`に準拠させれば、あなたの好きなようにカスタマイズできます。

```swift
public protocol SnapLikeCell: class {
    associatedtype Item
    var item: Item? { get set }
}
```

上記のようにSnapLikeCellにItemというassociatedtypeがあるので、ここに好きな型を入れてください。サンプルコードではStringを入れてますが、自作のモデル等を入れるのがおすすめです。

```swift
import UIKit
import SnapLikeCollectionView

class SampleCell: UICollectionViewCell, SnapLikeCell {
    @IBOutlet weak var titleLabel: UILabel!
    
    var item: String? {
        didSet {
            titleLabel.text = item
        }
    }
}
```

実際に上記のように使います。ItemのassociatedtypeにStringを入れた例です。

## CollectionViewにdataSourceやFlowLayoutを適用

コメントに説明を書いていきます。

```swift
import UIKit
import SnapLikeCollectionView

class ViewController: UIViewController {
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var collectionView: UICollectionView!
    
    // <SampleCell>の部分に先ほど作ったオリジナルのCellの型を入れる
    private var dataSource: SnapLikeDataSource<SampleCell>?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 真ん中にいる時と通常時のcellの大きさを入れる
        let cellSize = SnapLikeCellSize(normal: 100, center: 160)
        
        // cellSizeとcollectionViewを渡してdataSouceをinit
        dataSource = SnapLikeDataSource<SampleCell>(collectionView: collectionView, cellSize: cellSize)
        dataSource?.delegate = self
        
        // flowLayoutにもcellSizeを渡す
        let layout = SnapLikeCollectionViewFlowLayout(cellSize: cellSize)
        collectionView.collectionViewLayout = layout
        
        // ここはお決まりな感じ。decelerationRateとか以外と大事です。
        collectionView.registerNib(SampleCell.self)
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.decelerationRate = .fast
        collectionView.backgroundColor = .clear
        collectionView.delegate = dataSource
        collectionView.dataSource = dataSource
        
        // 先ほどCellのItemに入れた型のarrayをitemsに入れていきます。
        dataSource?.items = ["A", "B", "C", "D", "E"]
    }
}

// cellが選択されたらcellSelectedが呼ばれます
extension ViewController: SnapLikeDataDelegate {
    func cellSelected(_ index: Int) {
        DispatchQueue.main.async { [weak self] in
            let selectedItem: String = self?.dataSource?.items[index] ?? ""
            self?.titleLabel.text = selectedItem
        }
    }
}
```

# 課題

- CellにassociateTypeがあるのが微妙。深すぎない？でもこれがわかりやすかった
- Cellのサイズの決め方が曖昧。特にルールがない。なんとなく合わせてる
- padding調整等の機能がないから自分でチューニングするしかない

# まとめ

実は初めてのライブラリ配布でしたが、以外とすんなりできました。あらかじめプロジェクト内でEmbedded Framework化はしてたので、外に出してDemoアプリ作るだけで作れました。

⬇️ぜひスターを！！⭐️⭐️⭐️⭐️⭐️

https://github.com/kboy-silvergym/SnapLikeCollectionView