SwiftUI中navigationBarItems嵌入LottieView无法显示问题求助
问题原因
- 导航栏的UIBarButtonItem对自定义视图的尺寸约束是自适应内容的,你当前实现的LottieView没有显式设置宽高,父容器无法计算得到有效尺寸,所以Lottie视图渲染区域为0自然不可见;放在页面中央的LottieView因为VStack默认会撑开可用空间,所以能正常展示。
- 你将AnimationView定义为LottieView的存储属性不符合UIViewRepresentable的设计规范,视图更新时容易出现上下文不匹配的问题。
修复方案
- 给导航栏调用的LottieView显式设置frame尺寸,符合导航栏按钮的常规大小即可
- 调整LottieView的实现,将AnimationView的创建逻辑放到
makeUIView内部,避免存储属性带来的渲染异常 - 可选:给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
相关产品推荐
相关产品推荐

