lottie深入玩法
A、json文件和图片资源分开
delete 是json资源名字
/res/lottie/delete_anim_images是图片资源文件夹路径
JSON 中引用的图片名,必须与实际图片文件名一致
B、json文件和图片资源分开,并且图片加载不固定
比如我有7张图片,分别命名1~7,我可以根据逻辑从这7张图片里面选3张图片,放到lottie里面显示吗?
Lottie 本身不支持在动画过程中动态替换图片(比如从一堆图片中动态挑选几张替换),因为它的图片资源是绑定在 JSON 文件里的,JSON 中的
assets
数组会预定义所有图片名和 ID。
但!我们可以通过 “间接替换图片”
✅ 能实现需求的方法一:使用动态 ImageProvider 替换指定 ID 对应的图片
在 lottie-ios 4.x
中,你可以通过 实现自定义 ImageProvider 的方式,让某个 ID 返回你希望的图片内容。
🛠️ 一、动画 JSON 的设计要求(由设计师完成)
使用 Adobe After Effects + Bodymovin 插件导出
❗关键要求
-
设计师添加 3 个图片图层(img1、img2、img3)
-
命名保持统一(就是图层名叫
img1
、img2
、img3
) -
每个图层引用一张占位图(比如 placeholder.png)
-
导出时取消勾选 Embed Image(不要将图片嵌入 JSON)
-
勾选导出图像 → 会导出 JSON 和图像目录
最终导出结果是一个
.json
文件 + 一个images
文件夹,文件夹里包含img1.png
、img2.png
、img3.png
(占位图)
🧱 二、你的 App 中资源结构如下:
📦 MyApp
├── Assets
│ ├── lottie_template.json
│ └── images
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ └── 7.png
🧩 三、自定义 ImageProvider 来实现图片替换
class DynamicImageProvider: AnimationImageProvider {private let imageMap: [String: UIImage]init(imageMap: [String: UIImage]) {self.imageMap = imageMap}func imageForAsset(asset: ImageAsset) -> CGImage? {// asset.name 是 JSON 中 image 图层的 name,例如 "img1"guard let image = imageMap[asset.name] else { return nil }return image.cgImage}
}
🧪 四、使用示例代码(Swift 5.0)
// 假设你有 1~7.png 放在项目中
let allImageNames = ["1", "2", "3", "4", "5", "6", "7"]
let selected = allImageNames.shuffled().prefix(3)let imageMap: [String: UIImage] = ["img1": UIImage(named: selected[0])!,"img2": UIImage(named: selected[1])!,"img3": UIImage(named: selected[2])!
]let provider = DynamicImageProvider(imageMap: imageMap)guard let animation = LottieAnimation.named("lottie_template") else { return }let animationView = LottieAnimationView(animation: animation, imageProvider: provider)
animationView.frame = view.bounds
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
animationView.play()view.addSubview(animationView)
✅ 效果:每次启动动画时都会在 img1、img2、img3 图层上显示随机选的图片 🎉
✅ 前提是你的 Lottie JSON 中,assets
用的是 "img1"
, "img2"
这样的 ID。然后你可以在运行时替换这些 ID 对应的 UIImage 内容。
👀 注意事项
-
imageMap
中的 key 一定要与 JSON 中的图层名字一致(比如"img1"
) -
图片名与
UIImage(named:)
要匹配,确保加入到 Xcode 工程或 Assets 里 -
JSON 动画图层是固定的 3 个,你替换的是内容,不是数量
✅ 优点
-
一个 JSON 动画文件即可
-
图片资源独立管理,逻辑控制简单
-
没有生成多个动画文件,App 体积更小
疑问❓
🕹️ imageForAsset 是什么时候调用的?
-
当你用下面代码播放动画时:
let animationView = LottieAnimationView(animation: animation, imageProvider: provider)
animationView.play()
-
animationView.play()
开始渲染动画时,Lottie 内部会解析 JSON,发现某些图层是图片(例如"img1"
) -
然后 Lottie 就会调用你写的
imageForAsset(asset:)
方法 来获取它需要的图片
也就是说:
每当动画里有个
image
图层需要渲染,都会走一次imageForAsset()
—— 你可以在里面决定显示哪张图!
💥 会不会冲突?
不会!你自定义了 ImageProvider
,Lottie 会优先走你提供的图:
-
如果你没设置
imageProvider
,它就会去读"img1.png"
文件 -
如果你设置了自定义
DynamicImageProvider
,它就会调用:
imageForAsset(asset: ImageAsset(name: "img1"))
你返回什么图,它就显示什么图,和 JSON 原来的 p: img1.png
没关系了!