SwiftUI中NavigationSplitView非根视图时NavigationLink跳转失效
问题成因与修复方案
成因
当NavigationRoutes作为子视图嵌入父级NavigationStack的导航链路中时,NavigationSplitView内部的NavigationLink会被父级NavigationStack拦截。系统默认会尝试将点击的目标视图压入父导航栈,而非触发当前NavigationSplitView的selection绑定来更新详情区域,最终导致详情视图无响应。
修复方案
方案一:改用点击手势直接更新选择状态
移除NavigationLink,用普通文本配合点击手势直接修改currentSelection,完全避开父级导航栈的干扰:
struct NavigationRoutes: View { @State private var currentSelection: Destinations? enum Destinations { case empty case first case second } var body: some View { NavigationSplitView { List(selection: $currentSelection) { Section { Text("first view") .onTapGesture { currentSelection = .first } } Section { Text("second view") .onTapGesture { currentSelection = .second } } } } detail: { switch currentSelection ?? .empty { case .empty: EmptyView() case .first: Text("First redirect") case .second: Text("Second redirect") } } } }
方案二:给侧边栏添加独立导航栈
在NavigationSplitView的侧边栏(列表所在区域)包裹一个独立的NavigationStack,将其路径与currentSelection绑定,让内部的NavigationLink归属于这个局部导航栈,避免被父级拦截:
struct NavigationRoutes: View { @State private var currentSelection: Destinations? enum Destinations: Hashable { case empty case first case second } var body: some View { NavigationSplitView { NavigationStack(path: $currentSelection) { List(selection: $currentSelection) { Section { NavigationLink(value: Destinations.first) { Text("first view") } } Section { NavigationLink(value: Destinations.second) { Text("second view") } } } .navigationDestination(for: Destinations.self) { _ in EmptyView() } } } detail: { switch currentSelection ?? .empty { case .empty: EmptyView() case .first: Text("First redirect") case .second: Text("Second redirect") } } } }
注:方案二中需要让Destinations枚举遵循Hashable协议,因为NavigationStack的路径类型要求遵循该协议。
内容的提问来源于stack exchange,提问作者kwiky
相关产品推荐
相关产品推荐

