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

SwiftUI @Observable环境变量编译错误:无法找到$navigation作用域

问题解决:@Observable 类通过@Environment注入后无法使用$绑定的问题

问题重现

你定义了如下@Observable类:

@Observable class Navigation {
    var path = NavigationPath()
}

在App结构体中用@State创建实例并注入环境:

@main
struct ObservableTestApp: App {
    @State private var navigation = Navigation()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(navigation)
        }
    }
}

但在ContentView中使用@Environment获取实例并绑定$navigation.path时,出现编译错误:Cannot find '$navigation' in scope。

解决方法

在ContentView中,使用@Bindable包装@Environment注入的Observable实例,即可生成支持绑定的投影属性$:

struct ContentView: View {
    @Bindable @Environment(Navigation.self) private var navigation

    var body: some View {
        NavigationStack(path: $navigation.path) {
            // 你的视图内容
        }
    }
}

原因分析

  • 当@State定义在当前视图内部时,SwiftUI会自动为其生成带$的投影绑定,因为@State本身管理着视图内的状态。
  • 而通过@Environment传递@Observable实例时,获取到的只是普通的实例引用,SwiftUI不会自动为其生成绑定投影。@Bindable的作用就是为Observable类型创建一个可绑定的包装器,从而允许你通过$访问其属性的绑定。

@Observable 与 @ObservableObject 的行为差异

  • 旧方案中@ObservableObject配合@EnvironmentObject使用时,@EnvironmentObject内部已经隐式处理了绑定逻辑,所以可以直接用$访问投影属性。
  • 新的@Observable设计更轻量化,它没有绑定的默认支持,需要显式通过@Bindable来生成绑定,这是苹果为了简化状态管理模型、让状态绑定更可控而做的设计调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:51:05