You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中Lottie动画首次加载不播放问题及解决方案咨询

SwiftUI中从URL加载Lottie动画首次不播放的解决方案

问题根源

原代码存在几个核心问题导致首次加载不播放:

  • 从URL加载Lottie动画是异步操作,初始化时直接调用play(),此时动画资源还未加载完成,播放指令无效。
  • makeUIView未正确设置视图约束,可能导致动画视图布局异常,无法正常展示。
  • updateUIView中重复移除/添加子视图的逻辑冗余,且未针对动画加载状态做针对性处理。

修正后的代码

import SwiftUI
import Lottie

struct LottieView: UIViewRepresentable {
    let url: URL

    func makeUIView(context: Context) -> UIView {
        let containerView = UIView()
        let animationView = LottieAnimationView()
        
        // 基础配置
        animationView.contentMode = .scaleAspectFit
        animationView.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(animationView)
        
        // 设置约束,确保动画视图占满容器
        NSLayoutConstraint.activate([
            animationView.widthAnchor.constraint(equalTo: containerView.widthAnchor),
            animationView.heightAnchor.constraint(equalTo: containerView.heightAnchor)
        ])
        
        // 异步加载动画,加载完成后再播放
        animationView.setAnimation(from: url) { [weak animationView] result in
            guard case .success = result else {
                // 可在此添加加载失败的处理逻辑
                return
            }
            animationView?.loopMode = .loop
            animationView?.play()
        }
        
        return containerView
    }

    func updateUIView(_ uiView: UIView, context: Context) {
        // 无需重复操作,动画加载完成后会自动触发播放
    }
}

关键修改说明

  1. 异步加载回调触发播放:使用setAnimation(from:completion:)方法替代初始化时直接创建动画视图,在加载完成的回调中执行播放操作,确保动画资源就绪后再启动。
  2. 提前设置视图约束:在makeUIView中一次性完成约束配置,避免布局异常导致的动画不显示。
  3. 移除冗余逻辑:删除updateUIView中重复的视图操作,避免状态混乱。
  4. 弱引用避免内存泄漏:回调中使用weak引用animationView,防止循环引用。

额外优化建议

  • 若需要外部控制动画的播放/暂停,可以添加@Binding var isPlaying: Bool变量,在updateUIView中根据状态调用play()或pause()。
  • 加载失败时可添加占位视图或错误提示,提升用户体验。

内容的提问来源于stack exchange,提问作者Jabed Dhali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:12:14