티스토리 뷰
개요
이번에 개인 프로젝트를 하면서 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 |