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

SwiftUI 2.0无App/SceneDelegate时,EnvironmentObject设置位置咨询

在SwiftUI 2.0+中设置EnvironmentObject的正确位置

嘿,这个问题我太熟了!在SwiftUI 2.0及以后的版本里,我们告别了传统的AppDelegate和SceneDelegate,转而用遵循App协议的结构体作为应用入口,EnvironmentObject的设置反而变得更直接简洁——你只需要在应用的根视图层级里注入就行,完全不用碰UIKit的那套window逻辑。

具体实现步骤

  1. 先初始化你的ObservableObject实例(比如你的settings对象),直接在App结构体里声明就行
  2. 在WindowGroup(或者你用的其他Scene类型)的根视图上,通过.environmentObject()修饰符注入这个实例

举个完整的代码例子:

import SwiftUI

// 你的ObservableObject类,和之前的定义逻辑一致
class Settings: ObservableObject {
    @Published var themeColor = "blue"
    @Published var isDarkMode = false
}

@main
struct MyAwesomeApp: App {
    // 初始化全局共享的settings实例
    let settings = Settings()
    
    var body: some Scene {
        WindowGroup {
            // 直接在根ContentView上注入EnvironmentObject
            ContentView()
                .environmentObject(settings)
        }
    }
}

为什么这样可行?

这样注入后,整个应用所有层级的视图,只要通过@EnvironmentObject var settings: Settings声明,就能直接访问到这个共享的settings实例,和你之前在UIHostingController里注入的效果完全一致,而且更贴合SwiftUI的声明式编程风格。

多场景的特殊情况

如果你的应用有多个独立的Scene(比如iPad的多窗口、或者自定义的Scene),你可以选择:

  • 如果是全局共享的对象,就在所有Scene的根视图上都注入同一个实例
  • 如果是场景专属的对象,就在对应Scene的根视图里注入单独的实例

和旧写法的对比

之前你需要在AppDelegate里找到window,然后给UIHostingController添加environmentObject:

// 旧写法(SwiftUI 1.0)
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(settings))

现在的写法完全不需要依赖UIKit的API,所有逻辑都在SwiftUI的体系内完成,更简洁也更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:17:39