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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:55:12