Kolodaの使い方

アドベントカレンダー用の投稿

モチベーション

CocoaTinderみたいなViewを提供するライブラリがある。

github.com

これを使いたい。使う。

Carthageの準備

Cocoaライブラリのパッケージマネージャとして、だいたいみんなCocoaPodsかCarthageを使う。 ここではシンプルで軽量なCarthageを使う。

github.com

CarthageはHomebrewというパッケージマネージャでインストールできる。 Homebrewが入ってなかったら入れる。入れない理由がない。

$/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

brewが入ったらcarthageを入れる。

$brew install carthage

はいこんにちは

$carthage version

プロジェクトの準備

XcodeでSingle View Applicationプロジェクトを作る。

f:id:chikulla:20161129180441p:plain

作ったプロジェクトのルートディレクトリ(*.xcodeprojがあるとこ)にCartfileという名前のファイルを作る。

f:id:chikulla:20161129211646p:plain

今回はSwift3+Xcode8.1でiOSターゲットのサンプル作るが、 2016年11月時点でKolodaのmasterブランチはSwift3対応できてないので、Swift3ブランチをCarthageから使う。どんなライブラリを使うか、ライブラリのどのブランチを使うかは、Cartfileで指定できる。 Cartfileの中身はこんなん。

github "Yalantis/Koloda" "swift-3"

書き終わったら、ターゲットをiOSにするオプションをつけてcarthage updateする。

$carthage update --platform iOS

プロジェクトの設定

carthage updateが成功したら、Koloda.frameworkpop.frameworkがCarthageディレクトリ以下にできてる。

f:id:chikulla:20161129215122p:plain

Xcodeを開いて、プロジェクトルートのGeneralタブの一番下Linked Frameworks and Librariesに2つの.frameworkをドロップする。

f:id:chikulla:20161129215552p:plain

Build Phasesタブを開いて、左の+ボタン(Add a new build phase)を押し、New Run Script Phaseを選択する。

f:id:chikulla:20161129220059p:plain

Run Scriptのコマンドに

/usr/local/bin/carthage copy-frameworks

を書く。さらにInput Filesに

$(SRCROOT)/Carthage/Build/iOS/pop.framework
$(SRCROOT)/Carthage/Build/iOS/Koloda.framework

を書く。popがKolodaの前提ライブラリなので、先頭に持ってこないとビルド失敗する。こんな感じになるはず。

f:id:chikulla:20161129221502p:plain

なんでこんなスクリプトを設定しなきゃいけないのかというと、App Store のサブミッションのバグの対策らしい。 cmd+bでビルドして、エラーがでなかったらライブラリのロードは完了。

Viewを作る

デフォルトのstoryboardとコントローラをそのまま使う。 Main.storyboardを開く。右下のObject LibraryからViewを選択して、左ツリーのView Controller Scene > View Controller > Viewの下に配置する。 配置したViewをKolodaViewとして扱うために、右上のIdentity InspectorからClassをKolodaViewにする。ModuleをKolodaにする。

f:id:chikulla:20161130120624p:plain

配置したKolodaViewをViewの真ん中らへんにレイアウトする。

f:id:chikulla:20161129222753p:plain

ControllerとViewを繋げる

Main.storyboardを開きながら、右上の円が二つ重なってるアイコンを押して、ViewController.swiftを表示する。ViewController.swiftにimport Kolodaを書いてKolodaをインポートする。

f:id:chikulla:20161129223359p:plain

Main.storyboardのツリーからctrlを押しながらKoloda Viewをクリックして、ViewController.swiftのviewDidLoad()の上らへんにドラッグ&ドロップする。

f:id:chikulla:20161129223730p:plain

ドロップしたらNameをkolodaViewにして、Connectを押す。

f:id:chikulla:20161129223845p:plain

ViewControllerを書く

KolodaViewには最低限KolodaViewDatasourceを設定する必要がある。Datasourceは表示するカードの情報源となるプロトコルプロトコルJavaで言う所のInterfaceとだいたいおなじ。ここではViewControllerをDatasourceにする。

viewDidLoad()はWeb APIでいうところのwindow.onload。ここでkolodaViewのdataSourceをcontroller自身にする。 kolodaNumberOfCardsでカードの枚数を返す。ここでは10枚返すことにする。 koloda:viewForCardAtでカードのViewを返す。ここではコンパイルエラーを取るため、背景がグレーのUIViewを返す。

import UIKit
import Koloda

class ViewController: UIViewController {
    @IBOutlet var kolodaView: KolodaView!
    override func viewDidLoad() {
        super.viewDidLoad()
        kolodaView.dataSource = self
    }
}

extension ViewController: KolodaViewDataSource {
    func kolodaNumberOfCards(_ koloda: KolodaView) -> Int {
        return 10
    }
    func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
        let view = UIView(frame: koloda.bounds)
        view.backgroundColor = UIColor.gray
        return view
    }
}

extension A: BJavaでいうclass A implements Bだと思っていい。 ここではdataSourceとControllerのライフサイクルは同じだが、dataSourceを別クラスに切り出すような場合は、Controllerより先に勝手にdataSourceのインスタンスが破棄されないように気をつける。インスタンスの破棄はdeinitで追える。

deinit {
    print("destroyed")
}

表示されるカードが全部グレーだと寂しいので、ランダムな色の背景を持ったUIViewを返すことにする。UIColorをランダムなFloatのRGBから作れば、ランダムな背景のUIViewが作れる。ランダムなFloatとUIColorを生成するメソッドを作って、koloda:viewForCardAtから呼び出す。

    func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
        let view = UIView(frame: koloda.bounds)
        view.backgroundColor = randomColor()
        return view
    }
    func randomColor() -> UIColor {
        return UIColor(colorLiteralRed: randomFloat(), green: randomFloat(), blue: randomFloat(), alpha: 1)
    }
    func randomFloat() -> Float {
        return Float(Float(arc4random()) / Float(UInt32.max))
    }

できた

f:id:chikulla:20161130193005g:plain

全ソースはGitHub

github.com