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

SwiftUI中@Binding异常:需切换值才更新,求技术解析

SwiftUI 视图绑定通信异常原因解析

问题场景

你编写了测试SwiftUI视图间@Binding通信的代码,预期点击按钮后Sheet能显示选中的数字,但实际bindingValueInt有时会显示默认值0,而bindingValueBool总能正常触发Sheet弹出。测试代码如下:

struct SimpleButtonView: View {
    @Binding var bindingValueBool: Bool
    @Binding var bindingValueInt: Int
    var myNumber: Int
 
    var body: some View {
        Button(action: {
            // Change the values
            bindingValueBool = true
            bindingValueInt = myNumber
        }, label: {
            Text("Press me \(myNumber)")
        })
    }
}

struct TestView: View {
    @State var bindingValueBool: Bool = false
    @State var bindingValueInt: Int = 0
 
    var body: some View {
        ForEach(1 ... 10, id: \.self) {
            SimpleButtonView(bindingValueBool: $bindingValueBool, bindingValueInt: $bindingValueInt, myNumber: $0)
        }.sheet(isPresented: $bindingValueBool, content: {
            // This should show the number selected?
            // How come it's sometimes correct sometimes shows default value 0 as if the bindingValueInt hasn't got the updated value yet
            Text("This is the selected number \(bindingValueInt)")
        })
    }
}

异常原因

核心问题出在状态更新顺序与SwiftUI视图刷新机制的冲突上:

  • 按钮点击时,你先修改bindingValueBool为true,这个操作会立刻触发Sheet的展示流程。
  • 修改bindingValueInt的操作属于异步状态更新,SwiftUI会批量处理状态变更,无法保证它在Sheet初始化前完成同步。当Sheet提前渲染时,读取的还是bindingValueInt的旧值(0)。
  • 偶尔能显示正确值的情况,只是某次状态更新的顺序刚好让bindingValueInt先完成同步,Sheet渲染时拿到了新值,属于随机巧合。
  • 另外,isPresented绑定的Sheet一旦弹出,后续bindingValueInt的更新不会自动刷新Sheet内容(除非Sheet重新弹出),这也会加剧旧值残留的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:30:05