13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOS (その2)Advent Calendar 2018

Day 4

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

Posted at

SnapLikeCollectionView

スクリーンショット 2018-12-03 23.48.35.png

どんなライブラリ?

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

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

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

InstagramやSnapchatとの比較

作ったやつ Instagram Snapchat

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

インストール方法

Cocoapodsだけ用意しました。

Podfileに以下を追加してpod install

pod 'SnapLikeCollectionView'

使い方

Cellを準備

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

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

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

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を適用

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

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アプリ作るだけで作れました。

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

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?