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

SwiftUI中如何在兄弟视图间传递Environment对象并解决相关报错

问题根源

你出现报错和数据不共享的问题是两个错误共同导致的:

  • 你在VerseDetailView中通过@StateObject新建了一个局部的FavoritesViewModel实例,和你后续在App文件中创建的实例完全独立,两个实例的数据互不联通
  • 此前你仅给FavoritesView注入了环境对象,BookView所在的导航栈没有注入环境对象,且App层的全局实例没有用@StateObject修饰,会被意外重置

修复步骤

  1. 修改主App文件代码,全局持有唯一的FavoritesViewModel实例,并注入到所有子视图的公共父节点TabView上:
@main
struct YourAppName: App {
    // 用@StateObject修饰,保证App生命周期内实例唯一
    @StateObject private var favoritesViewModel = FavoritesViewModel()
    
    var body: some Scene {
        WindowGroup {
            TabView {
                NavigationView {
                    BookView() // VerseDetailView是该视图的子视图
                }
                .tabItem {
                    Image(systemName: "book")
                    Text("Books")
                       
                }
                NavigationView {
                    FavoritesView() 
                }
                .tabItem {
                    Image(systemName: "bookmark")
                    Text("Favorites")
                }
            }
            // 给整个TabView的所有子视图注入环境对象,两侧Tab都能拿到该实例
            .environmentObject(favoritesViewModel)
        }
    }
}
  1. 修改VerseDetailView的代码,删除局部新建的FavoritesViewModel实例,改为从环境中取全局实例:
// 删掉原来的@StateObject var favoritesViewModel = FavoritesViewModel()
@EnvironmentObject var favoritesViewModel: FavoritesViewModel
...
Button("Add to favorite") {
 favoritesViewModel.add(verse: verse)
}
  1. 你原本FavoritesView中@EnvironmentObject var favoritesViewModel: FavoritesViewModel的写法完全正确,无需修改。

原理说明

@EnvironmentObject是沿视图树向下传递的,只要在公共父视图注入一次,所有子视图都可以直接读取。核心要保证整个App中用到的FavoritesViewModel是同一个实例,不要在子视图中自行新建实例,否则会出现数据不互通、找不到实例的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:27:02