SwiftUI 2.0无App/SceneDelegate时,EnvironmentObject设置位置咨询
在SwiftUI 2.0+中设置EnvironmentObject的正确位置
嘿,这个问题我太熟了!在SwiftUI 2.0及以后的版本里,我们告别了传统的AppDelegate和SceneDelegate,转而用遵循App协议的结构体作为应用入口,EnvironmentObject的设置反而变得更直接简洁——你只需要在应用的根视图层级里注入就行,完全不用碰UIKit的那套window逻辑。
具体实现步骤
- 先初始化你的
ObservableObject实例(比如你的settings对象),直接在App结构体里声明就行 - 在
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
相关产品推荐
相关产品推荐

