iOSでlottie-iosを使ってリッチなアニメーションを簡単に実現してみる

最近のイケてるiOSアプリはアニメーションが入っているものが多いが、リッチなアニメーションを入れるには結構めんどうだったりする。Airbnbが出している[lottie-ios](https://github.com/airbnb/lottie-ios)というライブラリが非常に簡単で使いやすくてよかった。

## lottieとは
[lottie](https://airbnb.design/introducing-lottie/)
**Adobe After Effects**で作ったアニメーションを**json**に変換してそれをそのまま読み込ませてアプリ(iOS, Android, React Native)に組み込むAirbnbが出しているアニメーションライブラリ。ここではjsonを作成するところには触れずに、iOSで表示するところにフォーカスする。[ここ](https://www.lottiefiles.com/)に色々とサンプルが上がっているので、このサイトのものを利用してみる。下にある感じのアニメーションがアプリに簡単に組み込める。githubにあるlottie-iosというライブラリはstarも10000近くついており（ ~~2017/8/17時点で9948~~2020年3月24日時点で *19.2k* ）かなり人気である。

![lottie.gif](https://qiita-image-store.s3.amazonaws.com/0/122365/c2c284bf-ca1f-0b76-69c7-8916c9a659bc.gif)


## インストール

- Podなら`pod 'lottie-ios'`をPodfileに加えて、`pod install`。
- Carthageなら`github "airbnb/lottie-ios" "master"`をCartfileに加えて、`carthage update`。Linked Frameworks and Librariesの設定等も済ませる。

~~Swiftでこのライブラリを利用するので、Bridging-Headerファイル（なければ作成して、Build Settingに設定を付け足す必要がある）に`#import <Lottie/Lottie.h>`と追加する必要があるので注意。~~ LottieのVersion3以降は完全にSwiftで記述されており、この処理は必要ない（追記：2020年3月24日）。


```LottieSample-Bridging-Header.h
#ifndef LottieSample_Bridging_Header_h
#define LottieSample_Bridging_Header_h

#import <Lottie/Lottie.h>

#endif /* LottieSample_Bridging_Header_h */
```

## 基本的な使い方

[ここ](https://www.lottiefiles.com/)から試してみたいアニメーションのファイルを選択してjsonファイルをダウンロードする。Xcodeのプロジェクトに、ダウンロードしてきたjsonファイルを追加する。
今回はこのアニメーションを入れてみる。ダウンロードして、`Animation.json`という名前にしてXcodeに追加した。

![lottie2.gif](https://qiita-image-store.s3.amazonaws.com/0/122365/5bad139b-ed1d-e45a-e7c5-21443ba792ce.gif)

```ViewController.swift
import UIKit
import Lottie

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        showAnimation()
    }
   
    func showAnimation() {
        let animationView = AnimationView(name: "Animation")
        animationView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
        animationView.center = self.view.center
        animationView.loopMode = .loop
        animationView.contentMode = .scaleAspectFit
        animationView.animationSpeed = 1
        
        view.addSubview(animationView)
        
        animationView.play()
    }

}

```

こんな感じになる。
![lottie4.gif](https://qiita-image-store.s3.amazonaws.com/0/122365/f09aa277-368d-24cb-34c5-c758326cbf7c.gif)


## 一回再生したら消したい

`animationView.loopAnimation = false`にして、`animationView.play()`にcompletionHandlerを渡すように書き換える。

```ViewController.swift
import UIKit
import Lottie

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        showAnimation()
    }
    
    func showAnimation() {
        let animationView = AnimationView(name: "Animation")
        animationView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
        animationView.center = self.view.center
        animationView.loopMode = .loop
        animationView.contentMode = .scaleAspectFit
        animationView.animationSpeed = 1
        
        view.addSubview(animationView)
        
        animationView.play { finished in
            if finished {
                animationView.removeFromSuperview()
            }
        }
    }

}

```

## 任意のタイミングで終了させたい

~~`LOTAnimatinView`~~ `AnimationView`（追記：2020年3月24日）を任意のタイミングで`removeFromSuperview()`すればよい。

```ViewController.swift
import UIKit
import Lottie

class ViewController: UIViewController {

    lazy var loadingView: AnimationView = {
        let animationView = AnimationView(name: "Animation")
        animationView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
        animationView.center = self.view.center
        animationView.loopMode = .loop
        animationView.contentMode = .scaleAspectFit
        animationView.animationSpeed = 1
        
        return animationView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

    // 好きなタイミングでこれを呼ぶとアニメーションが始まる.
    func startLoading() {
        view.addSubview(loadingView)
        loadingView.play()
    }

    // 好きなタイミングでこれを呼ぶとアニメーションのViewが消える.
    func stopLoading() {
        loadingView.removeFromSuperview()
    }

    //// APIコールとかでstartLoading(), stopLoading()を呼ぶ.

}

```

## まとめ

[GitHub](https://github.com/ngo275/LottieSample)にあげておきました。

自分でjsonから作り出すのは少し手間がかかるが、すでに上がっているアニメーションは簡単に組み込めて楽しい。遊んでみてください。