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内容:
- 让
NormElements遵循Identifiable协议(若尚未实现):
struct NormElements: Identifiable { let id = UUID() // 你的其他属性,如name、pdfFileName等 }
- 修改代码,用
@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
相关产品推荐
相关产品推荐

