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

SwiftUI中TabView最后一页Lottie动画短暂显示后消失问题

解决SwiftUI TabView中Lottie动画短暂显示后消失的问题

我看到你遇到了在TabView第六页里Lottie动画仅短暂显示就消失的问题,其他场景下动画运行都正常。这是因为你在UIViewRepresentable的实现中,把AnimationView作为结构体的存储属性,而SwiftUI的视图结构体是值类型,当视图被重新渲染时,会导致动画视图的引用丢失,进而无法持续播放。

问题根源分析

你的LottieView结构体里,animationView是直接作为存储属性定义的:

var animationView = AnimationView()

由于SwiftUI的视图结构体是值类型,当SixScreen在TabView中被切换显示时,LottieView可能会被重新初始化,此时新的animationView实例和之前添加到UIView中的实例不是同一个。当updateUIView被调用时,你调用的是新实例的play()方法,而实际显示的旧实例没有被正确控制,最终导致动画停止。

修复方案

我们需要把AnimationView的引用存储在Coordinator中(Coordinator是类类型,属于引用类型),确保在视图生命周期内能够持续引用到同一个动画视图实例。修改后的LottieView代码如下:

struct LottieView: UIViewRepresentable {
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    var name: String!
    
    class Coordinator: NSObject {
        // 将AnimationView存储在Coordinator中(引用类型,不会丢失引用)
        var animationView = AnimationView()
    }
    
    func makeUIView(context: UIViewRepresentableContext<LottieView>) -> UIView {
        let view = UIView()
        let animationView = context.coordinator.animationView
        
        animationView.animation = Animation.named(name)
        animationView.contentMode = .scaleAspectFit
        animationView.loopMode = .loop
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
        
        NSLayoutConstraint.activate([
            animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
            animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
        
        // 在makeUIView中启动动画,确保首次加载时播放
        animationView.play()
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieView>) {
        // 通过Coordinator获取正确的动画视图实例
        let animationView = context.coordinator.animationView
        // 只有当动画未播放时才重新启动,避免重复触发导致动画重置
        if !animationView.isAnimationPlaying {
            animationView.play()
        }
    }
}

额外优化建议

  • 避免在updateUIView中每次都调用play():因为updateUIView可能会被SwiftUI频繁触发,重复调用play()会导致动画不断重置,添加播放状态检查能避免这个问题。
  • 可选的页面缓存优化:默认的PageTabViewStyle可能不会缓存所有页面,你可以给SixScreen添加.onAppear回调,确保进入页面时动画能正常启动,不过上面的修复已经解决了核心的引用问题,这一步属于锦上添花。

修改完成后,第六页的Lottie动画应该就能正常循环播放,不会再出现短暂显示后消失的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:32:32