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
相关产品推荐
相关产品推荐

