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

SwiftUI中navigationBarItems嵌入LottieView无法显示问题求助

问题原因

  • 导航栏的UIBarButtonItem对自定义视图的尺寸约束是自适应内容的,你当前实现的LottieView没有显式设置宽高,父容器无法计算得到有效尺寸,所以Lottie视图渲染区域为0自然不可见;放在页面中央的LottieView因为VStack默认会撑开可用空间,所以能正常展示。
  • 你将AnimationView定义为LottieView的存储属性不符合UIViewRepresentable的设计规范,视图更新时容易出现上下文不匹配的问题。

修复方案

  1. 给导航栏调用的LottieView显式设置frame尺寸,符合导航栏按钮的常规大小即可
  2. 调整LottieView的实现,将AnimationView的创建逻辑放到makeUIView内部,避免存储属性带来的渲染异常
  3. 可选:给LottieView增加可配置参数,方便不同场景适配

修复后完整代码如下:

import SwiftUI
import Lottie

struct NavTest: View {
    var body: some View {
        NavigationView {
            VStack {
                LottieView(name: "anyLocalLottieFile")
                    .frame(width: 200, height: 200)
            }
            .navigationBarTitle(Text("Menu"), displayMode: .inline)
            .edgesIgnoringSafeArea(.leading)
            .edgesIgnoringSafeArea(.bottom)
            .transition(.move(edge: .bottom))
            .navigationBarItems(trailing:
                // 显式设置导航栏按钮的Lottie尺寸
                LottieView(name: "anyLocalLottieFile", loopMode: .playOnce)
                    .frame(width: 24, height: 24)
            )
        }
        .navigationViewStyle(.stack)
    }
}

struct LottieView: UIViewRepresentable {
    var name: String
    var loopMode: LottieLoopMode = .loop
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }

    class Coordinator: NSObject {
        var animationView: AnimationView?
    }

    func makeUIView(context: UIViewRepresentableContext<LottieView>) -> UIView {
        let view = UIView(frame: .zero)
        // AnimationView放到makeUIView里创建,不要作为struct的存储属性
        let animationView = AnimationView()
        animationView.animation = Animation.named(name)
        animationView.contentMode = .scaleAspectFit
        animationView.loopMode = loopMode
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
        NSLayoutConstraint.activate([
            animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
            animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
        // 把animationView存在Coordinator里方便后续调用
        context.coordinator.animationView = animationView
        return view
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieView>) {
        context.coordinator.animationView?.play()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:36:03