티스토리 뷰

iOS-Development

Lottie

Gobans 2022. 5. 8. 00:04

개요

 이번에 개인 프로젝트를 하면서 Lottie 를 아주 많이 사용하였습니다. 간단하게 정리하여 포스팅하면 좋을 것 같아 글을 쓰게 되었습니다.

 


 

Lottie

Adobe After Effects 애니메이션을 Bodymovin과 함께 json으로 내보낸 후 모바일 및 웹에서 기본적으로 렌더링하는 안드로이드, iOS, 웹 및 윈도우용 라이브러리

(*Bodymovin : Adobe After Effects 를 json 으로 export 할 때 필요한 플러그인)

 

로티는 gif 와 다르게 벡터기반이기 떄문에 확대해도 이미지가 꺠지지 않고 용량이 적습니다. 사용자의 행동에 반응하는 인터렉션 애니메이션을 구현할 수 있습니다.

 

하지만 제작 난이도가 높다고 합니다. 이 부분은 이번 프로젝트에서는 제작까지 하지는 않았기 떄문에 잘 모르겠습니다.

 

 


SwiftUI 에서의 사용

먼저 패키지 관리자에서 Lottie 를 추가해줍니다. (https://github.com/airbnb/lottie-ios)

추가 후 로티 애니메이션을 관리해줄 struct를 만들어 줍니다.

 

//
//  LottieTestAnimation.swift
//  LottieTest
//
//

import Lottie
import SwiftUI
 
struct LottieTestAnimation: UIViewRepresentable {
    
    typealias UIViewType = UIView

    var filename: String
    
    var animationView = AnimationView()
    
    
    func makeUIView(context: UIViewRepresentableContext<LottieTestAnimation>) -> UIView {

        let view = UIView(frame: .zero)
        // 애니메이션을 파일명으로 생성
        animationView.animation = Animation.named(filename)
        // 애니메이션 크기 조절
        animationView.contentMode = .scaleAspectFit
        // 애니메이션 재생 모드(반복)
        animationView.loopMode = .playOnce
          // 애니메이션 속도 조절
        animationView.animationSpeed = 1
        // 애니메이션 실행
        // animationView.play()
        // 터치하면 실행되어야하기떄문에 주석처리
        
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
        
        NSLayoutConstraint.activate([
            //레이아웃의 높이와 넓이의 제약
            animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
            animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
        
        return view
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieTestAnimation>) {
        // do nothing
    }
    
}

 

사용시에는 이 LottieTestAnimation을 그대로 불러와 사용하면 됩니다.

 

저는 https://lottiefiles.com 에서 애니메이션을 Json 으로 다운받아 프로젝트 내에 저장하였습니다.

 

그 다음 사용하고자 하는 View 에서 바로 사용하면 됩니다.

 

//
//  ContentView.swift
//  LottieTest
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack{
            LottieTestAnimation(filename: "LottieHello")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

 

 

More


그런데 여기서 사용자가 터치했을 떄 애니메이션을 실행시키고 싶으면 설정을 조금 바꿔야합니다.

 

//
//  LottieTestAnimation.swift
//  LottieTest
//
//

import Lottie
import SwiftUI
 
struct LottieTestAnimation: UIViewRepresentable {
    
    typealias UIViewType = UIView

    var filename: String
    
    var animationView = AnimationView()
    
    
    func makeUIView(context: UIViewRepresentableContext<LottieTestAnimation>) -> UIView {

        let view = UIView(frame: .zero)
        // 애니메이션을 파일명으로 생성
        animationView.animation = Animation.named(filename)
        // 애니메이션 크기 조절
        animationView.contentMode = .scaleAspectFill
        // 애니메이션 재생 모드(반복)
        animationView.loopMode = .playOnce
          // 애니메이션 속도 조절
        animationView.animationSpeed = 1
        // 애니메이션 실행
        // animationView.play()
        // 터치하면 실행되어야하기떄문에 주석처리
        
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
        
        NSLayoutConstraint.activate([
            //레이아웃의 높이와 넓이의 제약
            animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
            animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
        
        return view
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieTestAnimation>) {
        // do nothing
    }
    
}

makeUIView 내부의 animationView.play()를 주석처리 후

 

//
//  ContentView.swift
//  LottieTest
//
//

import SwiftUI

struct ContentView: View {
    let lottieTestView = LottieTestAnimation(filename: "LottieHello")
    var body: some View {
        VStack{
            lottieTestView
                .onTapGesture {
                    lottieTestView.animationView.play()
                }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

애니메이션을 실행할 뷰안에서 변수 선언 후 body 안에 넣어줍니다.

 

그리고 onTapGesture 를 사용해 직접 해당 struct의 애니메이션 뷰를 재생하면 사용자가 터치 시 애니메이션이 실행되도록 구현할 수 있습니다.

 

 

 


    updateUIView 와 바인딩 변수를 활용하여 애니메이션을 끊어가면서 제어할수도 있습니다.

 

//
//  LottieTestAnimation.swift
//  LottieTest
//
//

import Lottie
import SwiftUI
 
struct LottieTestAnimation: UIViewRepresentable {
    
    typealias UIViewType = UIView

    var filename: String
    
    var animationView = AnimationView()
    
    @Binding var step:CGFloat
    
    
    func makeUIView(context: UIViewRepresentableContext<LottieTestAnimation>) -> UIView {

        let view = UIView(frame: .zero)
        // 애니메이션을 파일명으로 생성
        animationView.animation = Animation.named(filename)
        // 애니메이션 크기 조절
        animationView.contentMode = .scaleAspectFit
        // 애니메이션 재생 모드(반복)
        animationView.loopMode = .playOnce
          // 애니메이션 속도 조절
        animationView.animationSpeed = 1
        // 애니메이션 실행
        // animationView.play()
        // 터치하면 실행되어야하기떄문에 주석처리
        
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
        
        NSLayoutConstraint.activate([
            //레이아웃의 높이와 넓이의 제약
            animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
            animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
        
        return view
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieTestAnimation>) {
        animationView.play(fromProgress: step, toProgress: step+0.1)
    }
    
}

 

updateUIView는 바인딩 변수인 step이 변경될때마다 실행됩니다. play(fromProgress, toProgress) 로 애니메이션의 시작과 끝의 진행을 설정하여 실행할 수 있습니다.

 

//
//  ContentView.swift
//  LottieTest
//
//

import SwiftUI

struct ContentView: View {
    
    @State var step:CGFloat = 0
    @State var onTap:Bool = false
    
    var body: some View {
        VStack{
            let LottieTestView = LottieTestAnimation(filename: "LottieHello", step: $step)
            LottieTestView
                .onTapGesture {
                    self.step += 0.1
                }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

 

 

그 외에도 여러가지 애니메이션을 제어하는 방법이 docs에 자세히 나와있으니, 필요한 애니메이션 제어 동작을 한번 찾아보시길 바랍니다!

 

(로티 docs : https://airbnb.io/lottie/#/README)

 

'iOS-Development' 카테고리의 다른 글

Moya 에러 - 리팩토링  (0) 2023.09.27
Moya 에러 정리  (0) 2023.09.26
CoreData  (0) 2022.04.24
UserDefaults  (0) 2022.04.19
SwiftUI와 Storyboard  (0) 2022.04.03
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함