NavigationStack搭配@Observable连续导航失效问题排查
问题原因分析
你的代码核心问题在于子视图模型(Class1、Class2)中的path是mainClass.path的副本,而非绑定引用。当你在View1里调用model.path.append(...)时,修改的只是Class1实例里的局部数组,并没有更新NavigationStack绑定的mainClass.path,所以SwiftUI无法感知到路径变化,自然不会触发后续导航。
解决方案
不需要使用EnvironmentObject,只需要让子视图直接操作主模型的path绑定即可。具体调整如下:
- 移除Class1、Class2中多余的
path属性,因为它们不需要自己维护路径,直接使用主模型的路径绑定。 - 在创建子视图时,将主模型的实例传递下去(借助
@Bindable保持响应式绑定)。
修改后的完整代码:
import SwiftUI @Observable @MainActor final class MainClass { public enum Destination: Hashable { case view1 case view2 } var path: [Destination] = [] } struct View1: View { @Bindable var mainModel: MainClass var body: some View { Button("Go to View 2") { mainModel.path.append(.view2) } } } struct View2: View { var body: some View { Text("View 2") } } @MainActor struct ContentView: View { @Bindable var mainClass = MainClass() var body: some View { NavigationStack(path: $mainClass.path) { Button("Go to View 1") { mainClass.path.append(.view1) } .padding() .navigationDestination(for: MainClass.Destination.self) { destination in switch destination { case .view1: View1(mainModel: mainClass) case .view2: View2() } } } } } #Preview { ContentView() }
关键调整说明
- 简化
MainClass.Destination枚举,不再携带子模型(子视图不需要独立维护路径,直接依赖主模型的路径即可)。 - View1直接接收
MainClass的绑定实例,点击按钮时直接修改主模型的path,确保NavigationStack能实时感知路径变化并触发导航。 - 移除了Class1、Class2中不必要的Hashable实现和path属性,大幅简化代码结构。
如果你的子视图确实需要独立业务模型,可以将模型和主路径绑定分开传递,示例如下:
// 带业务数据的子模型 @Observable @MainActor final class Class1 { var someData: String init(someData: String) { self.someData = someData } } // 调整后的View1 struct View1: View { @Bindable var model: Class1 @Bindable var mainModel: MainClass var body: some View { VStack { Text("View1 业务数据: \(model.someData)") Button("Go to View 2") { mainModel.path.append(.view2) } } } } // 在导航目标中传递模型和主绑定 case .view1: View1(model: Class1(someData: "测试数据"), mainModel: mainClass)
这种方式既保留了子视图的业务模型,又能正确触发导航,同时满足不使用EnvironmentObject的要求。
内容的提问来源于stack exchange,提问作者miltenkot
相关产品推荐
相关产品推荐

