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

SwiftUI Sheet视图首次加载数据错误问题求助

问题描述

我的App加载NormDetailView时存在异常:首次打开Sheet总是加载默认标准(en103052),而非用户选中的标准,但首次加载默认值后,后续能正常加载用户选中的标准。此前使用NavigationLink时完全符合预期,相关代码如下:

VStack {
        List {
            ForEach(normsSearch) {norm in
                Section(header: Text(norm.title)) {
                    ForEach(norm.elements) { element in
                        NavigationLink(destination: NormDetailView(chosenNormElement: element)) {
                            Text(element.name)
                        }
                    }
                }
            }
        }

目前改用Sheet实现,已通过断点确认首次加载的是默认标准,附上当前代码:

//控制NormDetailsView显示的布尔值
@State var showingSheet = false

//用于.sheet部分的变量
@State var chosenElement: NormElements = en103052

var body: some View {
    NavigationView {
        VStack {
            List {
                ForEach(normsSearch) {norm in
                    Section(header: Text(norm.title)) {
                        ForEach(norm.elements) { element in
                            Button(element.name) {
                                //将element值传递给上方定义的chosenElement
                                chosenElement = element
                                showingSheet.toggle()
                            }
                        }
                    }
                }
            }.sheet(isPresented: $showingSheet, content: {
                //需传入chosenNormElement以获取用户点击按钮对应的PDF文件名
                NormDetailsView(chosenNormElement: chosenElement)
            })
解决方案

这是SwiftUI使用sheet(isPresented:)的常见问题:Sheet的内容会在视图初始化时提前创建,而非触发显示时才更新。首次打开时chosenElement还是初始默认值,因此传递给NormDetailView的是默认标准。

改用sheet(item:)即可解决,它会在绑定的item变化时重新创建Sheet内容:

  1. 让NormElements遵循Identifiable协议(若尚未实现):
struct NormElements: Identifiable {
    let id = UUID()
    // 你的其他属性,如name、pdfFileName等
}
  1. 修改代码,用@State var selectedElement: NormElements?替代原有的showingSheet和chosenElement:
@State var selectedElement: NormElements?

var body: some View {
    NavigationView {
        VStack {
            List {
                ForEach(normsSearch) {norm in
                    Section(header: Text(norm.title)) {
                        ForEach(norm.elements) { element in
                            Button(element.name) {
                                selectedElement = element
                            }
                        }
                    }
                }
            }.sheet(item: $selectedElement) { element in
                NormDetailsView(chosenNormElement: element)
            }
        }
    }
}

这样每次点击按钮时,selectedElement会被设置为用户选中的元素,sheet(item:)会感知到变化,创建新的NormDetailView并传入正确值,首次打开也能加载用户选中的标准。

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

相关产品推荐
方舟 Agent Plan

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

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