SwiftUI Sheet无法识别更新后的State值问题咨询
SwiftUI Sheet无法识别State更新值的解决方案
问题出在.sheet(isPresented:)的工作机制上:这个修饰符的内容闭包是在父视图首次渲染时被捕获的,它会固定持有当时data的引用。哪怕后续data通过异步任务更新了,Sheet的内容闭包不会重新执行,所以始终拿不到最新的data值。而Button的action闭包是每次点击都会触发执行,自然能获取到最新的data。
解决方法:改用.sheet(item:)修饰符
.sheet(item:)会监听绑定的Identifiable类型对象,当对象从nil变为非nil时自动展示Sheet,并且每次对象更新都会重新生成Sheet内容,确保拿到最新值。
修改后的完整代码如下:
struct ContentView: View { @State var data: SomeDataClass? = nil var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Button(action: { if let theData = self.data { print("Button sees the new data") } else { print("Button doesn't see the new data") } }) { Label("Tap me", systemImage: "folder.badge.plus") } } .padding() .task { DispatchQueue.global().asyncAndWait { data = SomeDataClass() } } // 通过data的状态控制Sheet展示 .sheet(item: $data) { _ in Text("Sheet sees new data!") } } } // 让数据类遵循Identifiable协议,满足sheet(item:)的要求 class SomeDataClass: Identifiable { let id = UUID() }
关键改动说明:
- 删除了
showSheet状态,直接用data的nil/非nil状态控制Sheet的显示和隐藏 - 让
SomeDataClass实现Identifiable协议,生成唯一的id属性,这是.sheet(item:)的强制要求 - 当
data被异步任务赋值为非nil后,Sheet会自动展示;点击按钮时,Sheet内容已经是基于最新data生成的版本
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

