Lottieことはじめ
Lottieとは
Airbnb謹製のアニメーションツールでAfterEffectsでexportしたアニメーションをiOS、Androidで再生できるというすぐれものです。
上記のGIFはlottie-iosより転載
僕自身はこういうアニメーションはあまり好きではないのですが、
味気なさがなくなりますね!
ということで、シンプルなハンバーガーアイコンのスイッチを例に使い始めるまでの流れをまとめてみました。
1. Carthageで組み込み
github "airbnb/lottie-ios" "master"
cartfileに上記を記述してcarthage update --platform iOS
して、プロジェクトに組み込むだけですね。
2. スイッチを組み込む
LOTAnimatedSwitch
というクラスがあるのでそれを使います。
LOTAnimatedSwitch.h
をみるとスイッチを作成するクラスメソッドが用意されてるのでこちらを使います。
/// Convenience method to initialize a control from the Main Bundle by name + (instancetype _Nonnull)switchNamed:(NSString * _Nonnull)toggleName; /// Convenience method to initialize a control from the specified bundle by name + (instancetype _Nonnull)switchNamed:(NSString * _Nonnull)toggleName inBundle:(NSBundle * _Nonnull)bundle;
toggleNameにはアニメーションを記述したjsonファイルを指定する必要があります。
LottieではLottieFilesといって、
アニメーションをクリエイティブ・コモンズライセンスで公開しているストアがありますのでそこからダウンロードしてきます。
今回はハンバーガーアイコンをダウンロードしてきます。
ダウンロードされたzipを解答するとAfterEffectsのプロジェクトファイルと、Export済みのjsonがはいっているのでjsonをプロジェクトに組み込みます
let animatedSwitch = LOTAnimatedSwitch.init(named: "Hamburger")
これで読み込めるようになりました。
3. スイッチのアニメーションの範囲を決める
このままではアニメーションはうまく動きません。なぜならスイッチのON/OFFに対してのアニメーションの対応付をしていないからです。
スイッチはoff -> on
のアニメーションとon -> off
のアニメーションがあります
この間ですね。
LOTAnimatedSwitch.h
をみるとアニメーションの範囲を割合で設定するメソッドが用意されています
- (void)setProgressRangeForOnState:(CGFloat)fromProgress toProgress:(CGFloat)toProgress NS_SWIFT_NAME(setProgressRangeForOnState(fromProgress:toProgress:)); - (void)setProgressRangeForOffState:(CGFloat)fromProgress toProgress:(CGFloat)toProgress NS_SWIFT_NAME(setProgressRangeForOffState(fromProgress:toProgress:));
先ほどダウンロードしたHamburger.json
ではoff->on->off
ということでonに戻るまでのアニメーションが記述されています。
アニメーションの進捗割合に対応付けると
off -> on
: 0 -> 0.5
on -> off
: 0.5 -> 1.0
と表すことができます。
したがって、setProgressの記述は以下のようになります。
animatedSwitch.setProgressRangeForOnState(fromProgress: 0, toProgress: 0.5) animatedSwitch.setProgressRangeForOffState(fromProgress: 0.5, toProgress: 1.0)
この進捗割合はアニメーションの元ファイルに依存します。
off -> on
: 0 -> 1.0
on -> off
: 1.0 -> 0
で表せる場合もあるでしょう。
ということで、アニメーションの対応付が完了し、スイッチの作成ができました。
※レイアウトのコードは本筋から外れるので記載していません
4. 動かしてみる
タップしてるのですがわかりづらいですね(汗)
ということで、アニメーションの組み込みができました。
5. InterfaceBuilderで組み込めるようにしてみる
InterfaceBuilderで必要な要素だけを設定したらいい感じに動いてほしいです。
毎度、アニメーションの対応付のコードを書くのは面倒です。
ということで、InterfaceBuilderで設定できるようにします。
LottieSwitchView.swift
@IBDesignable @IBInspectable
を使って、Interface Builderでアニメーションを定義できるようにします
import UIKit import Lottie @IBDesignable class LottieSwitchView: UIView { @IBInspectable var filename: String = "" @IBInspectable var fromProgressToOn: CGFloat { set(newValue) { _fromProgressToOn = LottieSwitchView.shrinkInZeroToOne(value: newValue) } get { return _fromProgressToOn } } @IBInspectable var toProgressToOn: CGFloat { set(newValue) { _toProgressToOn = LottieSwitchView.shrinkInZeroToOne(value: newValue) } get { return _toProgressToOn } } @IBInspectable var fromProgressToOff: CGFloat { set(newValue) { _fromProgressToOff = LottieSwitchView.shrinkInZeroToOne(value: newValue) } get { return _fromProgressToOff } } @IBInspectable var toProgressToOff: CGFloat { set(newValue) { _toProgressToOff = LottieSwitchView.shrinkInZeroToOne(value: newValue) } get { return _toProgressToOff } } //// actual value private var _fromProgressToOn: CGFloat = 0 private var _toProgressToOn: CGFloat = 0.5 private var _fromProgressToOff: CGFloat = 0.5 private var _toProgressToOff: CGFloat = 1.0 override func awakeFromNib() { super.awakeFromNib() let animatedSwitch = LOTAnimatedSwitch.init(named: filename) animatedSwitch.setProgressRangeForOffState(fromProgress: fromProgressToOff, toProgress: toProgressToOff) animatedSwitch.setProgressRangeForOnState(fromProgress: fromProgressToOn, toProgress: toProgressToOn) self.addSubview(animatedSwitch) animatedSwitch.fitToParent() } } private extension LottieSwitchView { static func shrinkInZeroToOne(value: CGFloat) -> CGFloat { return min(1.0, max(value, 0)) } }
これで、InterfaceBuilderでファイル名、アニメーションの範囲を指定できるようになりました
InterfaceBuilder上ではUIViewで枠だけを作っていて
awakeFromNibで内部的にLOTAnimatedSwitch
を作ってaddSubviewしています。
fitToParent
は親Viewと同じframeになるようにConstraintsを設定しているだけです。
以上、Lottie事始めでした。
リポジトリ
https://github.com/matsuokah/LottieSamplegithub.com
次は、「AfterEffectsからアニメーションのJSONをExportする」記事を書こうと思います
↓書きました