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

SwiftUI中如何为类内的计算属性设置可绑定的Binding

问题原因

首先拆解两次尝试的错误点:

  • 第一次实现的proxy是普通计算属性:SwiftUI 只有对@Published、@State这类属性包装器修饰的属性,才会通过$前缀自动生成绑定对象,普通计算属性不支持该语法。
  • 第二次把proxy改为直接返回Binding<Item?>:
    1. 此时model.proxy本身就是绑定类型,不需要$前缀获取绑定
    2. 你写的model.proxy.value拿到的是Binding<Double?>可选类型,和SubView要求的非可选BinaryFloatingPoint绑定类型不兼容,所以绑定失效。
最终实现方案

以下实现同时支持两种调用方式:直接写model.proxy.value = 10修改值,也可以直接传递绑定给子组件:

import SwiftUI

struct Item {
    var value: Double
}

class Model: ObservableObject {
    @Published var items: [Item] = [Item(value: 1), Item(value: 2), Item(value: 3)]
    
    // 用于直接读写的普通计算属性
    var proxy: Item {
        get { items[1] }
        set { items[1] = newValue }
    }
    
    // 用于传递绑定的计算属性
    var proxyBinding: Binding<Item> {
        Binding(
            get: { self.proxy },
            set: { self.proxy = $0 }
        )
    }
}

struct ContentView: View {
    @StateObject var model = Model()
    var body: some View {
        VStack {
            Text("Value: \(model.proxy.value)")
            
            // 方式1:直接修改,正常生效
            Button(action: {
                model.proxy.value = 123
            }, label: { Text("修改为123") })
            
            // 方式2:传递绑定给子组件,通过proxyBinding的动态成员查找拿到value的绑定
            SubView(value: model.proxyBinding.value)
        }.padding()
    }
}

struct SubView <B:BinaryFloatingPoint> : View {
    @Binding var value: B
    var body: some View {
        Button( action: {
            value = 100
        }, label: { Text("修改为100") })
    }
}
可选场景适配

如果你需要保留proxy的可选特性(比如选中项不存在时返回nil),可以用Binding的可选转换能力,拆包后再传给子组件,避免强制解包崩溃。

内容的提问来源于stack exchange,提问作者Jayåk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:54:06