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

SwiftUI:如何为环境对象ViewModel的属性创建Binding?

将Observable ViewModel的属性绑定传递给子View的实现方法

你需要把环境中ViewModel的showDetails属性以Binding形式传递给DetailsButton,有两种简洁的实现方式,适配iOS 17/macOS 14的新Observation框架:

方式一:用@Bindable包装环境ViewModel(推荐)

通过@Bindable修饰环境中的Observable对象,就能像使用@State一样用$语法直接生成Binding,写法最简洁:

完整代码

@Observable class ViewModel {
    var showDetails: Bool
    // 添加默认初始化方法,方便实例化
    init(showDetails: Bool = false) {
        self.showDetails = showDetails
    }
}

struct TestApp: App {
    @State var vm = ViewModel()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(vm)
        }
    }
}

struct ContentView: View {
    // 用@Bindable和@Environment组合,直接生成可绑定的ViewModel实例
    @Bindable @Environment(ViewModel.self) private var vm
    
    var body: some View {
        VStack {
            // 直接传递$vm.showDetails,和原示例的用法一致
            DetailsButton(showDetails: $vm.showDetails)
            if vm.showDetails {
                Text("This is my message!")
            }
        }
    }
}

struct DetailsButton: View {
    @Binding var showDetails: Bool
    var body: some View {
        Button("\(showDetails ? "Hide" : "Show") Details") {
            showDetails.toggle()
        }
    }
}

方式二:手动构造Binding

如果需要自定义属性的读取/赋值逻辑,可以手动通过Binding(get:set:)构造器生成绑定:

完整代码

@Observable class ViewModel {
    var showDetails: Bool
    init(showDetails: Bool = false) {
        self.showDetails = showDetails
    }
}

struct TestApp: App {
    @State var vm = ViewModel()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(vm)
        }
    }
}

struct ContentView: View {
    @Environment(ViewModel.self) private var vm
    
    var body: some View {
        VStack {
            DetailsButton(
                showDetails: Binding(
                    get: { vm.showDetails },
                    set: { vm.showDetails = $0 }
                )
            )
            if vm.showDetails {
                Text("This is my message!")
            }
        }
    }
}

struct DetailsButton: View {
    @Binding var showDetails: Bool
    var body: some View {
        Button("\(showDetails ? "Hide" : "Show") Details") {
            showDetails.toggle()
        }
    }
}

两种方式都能实现和原示例完全一致的功能,推荐使用方式一,语法更符合SwiftUI的设计习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:47:28