前情提要
因为要改版我的“存钱猪猪”应用,在应用的启动环境,想要提供一个加载动画,防止让用户存在视觉的卡顿效果。
因此在Gif动画和lottie动画中,选择使用lottie动画作为后续应用动画的首选。
操作流程
配置Xcode
在Xcode中打开对应的项目文件,点击左侧顶部的项目名称,选择选项卡中的PROJECT -> Package Dependencies -> Packages,点击左下角的添加按钮。
在弹出框中输入下面的Git仓库名称,然后点击“Add Package”按钮。
https://github.com/airbnb/lottie-ios
等待片刻,安装完成。然后在Add to Target中选择我们的项目,再点击“Add Package”按钮,将lottie添加到我们的项目中。
配置文件
首先,我们将lottie的json文件导入到我们的项目中,我在这里先创建了一个animation.scnassets文件夹来管理lottie动画文件,右击选择“Add Files to 项目名”。
选中对应的lottie动画的json文件,导入到Xcode中。
导入后的效果图:
创建一个LottieView视图文件,具体代码如下:
import SwiftUI
import Lottie
struct LottieView: UIViewRepresentable {
var filename: String
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
// 创建 Lottie 动画视图
let animationView = LottieAnimationView(name: filename) // 使用 LottieAnimationView 而不是 AnimationView
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
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: Context) {}
}
最后,我们在视图中使用:
LottieView(filename: "loading") // 替换为你的 Lottie 文件名
代码进行lottie动画的展示。
完成效果:
资源
LottieFiles: https://lottiefiles.com/
扩展知识
如果想要控制lottie动画的播放和循环次数,可以使用下面的代码:
import SwiftUI
import Lottie
struct LottieView: UIViewRepresentable {
var filename: String
var isPlaying: Bool // 控制是否播放
var playCount: Int // 播放次数,0 表示无限循环
var isReversed: Bool // 是否倒放
class Coordinator {
var parent: LottieView
init(parent: LottieView) {
self.parent = parent
}
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
// 创建 Lottie 动画视图
let animationView = LottieAnimationView(name: filename)
animationView.contentMode = .scaleAspectFit
animationView.translatesAutoresizingMaskIntoConstraints = false
animationView.loopMode = playCount == 0 ? .loop : .playOnce
view.addSubview(animationView)
NSLayoutConstraint.activate([
animationView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
animationView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
animationView.topAnchor.constraint(equalTo: view.topAnchor),
animationView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
if isPlaying {
playAnimation(animationView, playCount: playCount, isReversed: isReversed)
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
guard let animationView = uiView.subviews.first as? LottieAnimationView else { return }
if isPlaying {
playAnimation(animationView, playCount: playCount, isReversed: isReversed)
} else {
animationView.stop()
}
}
// 播放动画的辅助方法
private func playAnimation(_ animationView: LottieAnimationView, playCount: Int, isReversed: Bool) {
animationView.animationSpeed = isReversed ? -1 : 1
if isReversed {
animationView.currentProgress = 1 // 从最后一帧开始倒放
}
if playCount == 0 {
animationView.loopMode = .loop
animationView.play()
} else {
animationView.loopMode = .playOnce
animationView.play { _ in
if playCount > 1 {
playAnimation(animationView, playCount: playCount - 1, isReversed: isReversed)
}
}
}
}
}
SwiftUI中使用按钮控制播放效果:
struct ContentView: View {
@State private var isPlaying = false
@State private var isReversed = false
var body: some View {
VStack {
LottieView(filename: "success", isPlaying: isPlaying, playCount: 2, isReversed: isReversed)
.frame(width: 200, height: 200)
HStack {
Button(action: {
isReversed = false
isPlaying = true
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
isPlaying = false
}
}) {
Text("正向播放")
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(8)
}
Button(action: {
isReversed = true
isPlaying = true
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
isPlaying = false
}
}) {
Text("倒放")
.padding()
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(8)
}
}
}
}
}
实现逻辑
1、默认暂停:通过 isPlaying 的状态控制是否播放。
2、播放指定次数:通过 playCount 传递目标次数。
3、延迟停止:在按钮触发时,通过 DispatchQueue 设置动画播放的时间上限。
4、倒放控制:通过 isReversed 参数设置动画速度为 -1。