SwiftUI NavigationStack跳转异常问题求助
将NavigationView替换为NavigationStack后,遇到跳转异常问题。其中一个视图的NavigationStack工作正常,但给它的前置视图添加导航链接时出现异常。
工作异常的NavigationStack代码
enum HomeRoute: Hashable { case UserProfile case HomeAnalytics } struct HomeView: View { var title = "SwiftUIToolbar" @State var path = NavigationPath() //required for SignIn & SignOut. @EnvironmentObject var viewModel:AppViewModel //@StateObject private var homeNavigation: HomeNavigationViewModel = HomeNavigationViewModel() var body: some View { NavigationStack(){ VStack(){ HeaderView(path: $path) TabView { FridgePantryView() .tabItem { Image(systemName: "carrot") Text("Fridge & Pantry") } Text("Recipes") .font(.system(size: 30, weight: .bold, design: .rounded)) .tabItem { Image(systemName: "fork.knife") Text("Recipes") } Text("Shopping") .font(.system(size: 30, weight: .bold, design: .rounded)) .tabItem { Image(systemName: "cart") Text("Shopping") } } } } } } struct HeaderView: View { var body: some View { NavigationStack() { HStack{ HStack{ //Click Through for Settings View NavigationLink("Home",value: HomeRoute.HomeAnalytics) } .padding(.horizontal, 15.0) .padding(.vertical, 3.0) Spacer() HStack (spacing: 20.0) { //Click Through for Settings View NavigationLink("UserProfile",value: HomeRoute.UserProfile) } } .navigationDestination(for: HomeRoute.self) { route in switch route { case .UserProfile: SettingsView() case .HomeAnalytics: SettingsView() } } } } }
可正常工作的承接视图代码
enum SettingsRoute: Hashable { case Profile case Settings case GiveUsFeedback case InviteFriends case HelpSupport case SavedRecipes case LogOut } struct SettingsView: View { @State private var path = NavigationPath() //var ListOfSettings: [ListOfSettings] = [ProfileView(),Settings(),GiveUsFeedback(),InviteFriends(),HelpSupport(),SavedRecipes(),LogOut()] @EnvironmentObject var viewModel: AppViewModel //Array of Titles wanted for List view. //private var SettingsContentTitle: [String] = ["Profile","Settings","Give us Feedback","Invite Friends","Help & Support","Saved Recipes","Log Out"] var body: some View { NavigationStack() { VStack(){ List() { NavigationLink("Profile", value: SettingsRoute.Profile) .padding() NavigationLink("Settings", value: SettingsRoute.Settings) .padding() NavigationLink("Give us Feedback", value: SettingsRoute.GiveUsFeedback) .padding() NavigationLink("Invite Friends", value: SettingsRoute.InviteFriends) .padding() NavigationLink("Help & Support", value: SettingsRoute.HelpSupport) .padding() NavigationLink("Saved Recipes", value: SettingsRoute.SavedRecipes) .padding() NavigationLink("Log Out", value: SettingsRoute.LogOut) .padding() } .listStyle(.inset) //Created a navigation switch for NavigationLink paths above. ///communicates with enum above. .navigationDestination(for: SettingsRoute.self) { route in switch route { case .Profile: ProfileView() case .Settings: Settings() case .GiveUsFeedback: GiveUsFeedback() case .InviteFriends: InviteFriends() case .HelpSupport: HelpSupport() case .SavedRecipes: SavedRecipes() case .LogOut: LogOut() } } Spacer() signoutButton() } .navigationTitle("Hi") } } }
问题原因及修复方案
核心问题
代码中嵌套了多个独立的NavigationStack:
HomeView、HeaderView、SettingsView各自创建了自己的NavigationStack- 这种嵌套会导致导航层级混乱,跳转逻辑冲突,最终引发异常
NavigationStack在SwiftUI中应作为单层级主导航容器使用,子视图无需重复创建,复用父容器即可。
修复步骤
- 移除
HeaderView中的NavigationStack,将导航链接和navigationDestination合并到HomeView的主导航容器中 - 通过
@Binding传递NavigationPath,统一管理导航栈状态 - 移除
SettingsView中的NavigationStack,复用父级导航容器
修复后的HomeView和HeaderView代码
enum HomeRoute: Hashable { case UserProfile case HomeAnalytics } struct HomeView: View { var title = "SwiftUIToolbar" @State var path = NavigationPath() @EnvironmentObject var viewModel: AppViewModel var body: some View { NavigationStack(path: $path) { VStack { HeaderView() TabView { FridgePantryView() .tabItem { Image(systemName: "carrot") Text("Fridge & Pantry") } Text("Recipes") .font(.system(size: 30, weight: .bold, design: .rounded)) .tabItem { Image(systemName: "fork.knife") Text("Recipes") } Text("Shopping") .font(.system(size: 30, weight: .bold, design: .rounded)) .tabItem { Image(systemName: "cart") Text("Shopping") } } } .navigationDestination(for: HomeRoute.self) { route in switch route { case .UserProfile, .HomeAnalytics: SettingsView(path: $path) } } } } } struct HeaderView: View { var body: some View { HStack { HStack { NavigationLink("Home", value: HomeRoute.HomeAnalytics) } .padding(.horizontal, 15.0) .padding(.vertical, 3.0) Spacer() HStack(spacing: 20.0) { NavigationLink("UserProfile", value: HomeRoute.UserProfile) } } } }
修复后的SettingsView代码
enum SettingsRoute: Hashable { case Profile case Settings case GiveUsFeedback case InviteFriends case HelpSupport case SavedRecipes case LogOut } struct SettingsView: View { @Binding var path: NavigationPath @EnvironmentObject var viewModel: AppViewModel var body: some View { VStack { List { NavigationLink("Profile", value: SettingsRoute.Profile) .padding() NavigationLink("Settings", value: SettingsRoute.Settings) .padding() NavigationLink("Give us Feedback", value: SettingsRoute.GiveUsFeedback) .padding() NavigationLink("Invite Friends", value: SettingsRoute.InviteFriends) .padding() NavigationLink("Help & Support", value: SettingsRoute.HelpSupport) .padding() NavigationLink("Saved Recipes", value: SettingsRoute.SavedRecipes) .padding() NavigationLink("Log Out", value: SettingsRoute.LogOut) .padding() } .listStyle(.inset) Spacer() signoutButton() } .navigationTitle("Hi") .navigationDestination(for: SettingsRoute.self) { route in switch route { case .Profile: ProfileView() case .Settings: Settings() case .GiveUsFeedback: GiveUsFeedback() case .InviteFriends: InviteFriends() case .HelpSupport: HelpSupport() case .SavedRecipes: SavedRecipes() case .LogOut: LogOut() } } } }
关键说明
- 所有导航逻辑(链接、目标页)都应挂载到同一个
NavigationStack下 - 通过
NavigationPath统一管理导航栈状态,跨层级传递使用@Binding - 子视图仅需添加对应的
navigationDestination,无需重复创建导航容器
内容的提问来源于stack exchange,提问作者DogDogDog
相关产品推荐
相关产品推荐

