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

如何高效判断NavigationView中是否存在激活的NavigationLink

高效判断任意NavigationLink是否激活的方法

方法一:使用NavigationStack(iOS 16+ 推荐)

如果项目已适配iOS16及以上,直接借助NavigationStack的NavigationPath跟踪导航栈状态,无需给每个NavigationLink绑定独立的isActive:

struct ContentView: View {
    @State private var navigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            List {
                NavigationLink("跳转到页面1", value: "Page1")
                NavigationLink("跳转到页面2", value: "Page2")
                // 更多NavigationLink...
            }
            .navigationDestination(for: String.self) { value in
                Text("\(value) 页面")
            }
            .toolbar {
                Button("是否有激活的链接?") {
                    // 通过path长度判断,大于0则说明存在激活的NavigationLink
                    let hasActiveLink = navigationPath.count > 0
                    print(hasActiveLink)
                }
            }
        }
    }
}

核心逻辑:NavigationPath会自动记录导航栈层级,只要栈内有元素(count > 0),就代表有页面被推送,即存在激活的链接。

方法二:兼容iOS15及以下的NavigationView方案

若需适配旧版本,可通过两种方式实现统一状态管理:

方案A:自定义导航状态管理器

创建全局状态对象,结合UIKit导航栈数量判断激活状态:

class NavigationState: ObservableObject {
    @Published var hasActiveLink = false
}

struct ContentView: View {
    @StateObject private var navState = NavigationState()
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("页面1", destination: Text("页面1"))
                NavigationLink("页面2", destination: Text("页面2"))
                // 更多NavigationLink...
            }
            .toolbar {
                Button("检查激活状态") {
                    if let navController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
                        navState.hasActiveLink = navController.viewControllers.count > 1
                    }
                    print(navState.hasActiveLink)
                }
            }
            .environmentObject(navState)
        }
    }
}

方案B:利用UIKit导航控制器代理

通过UIViewControllerRepresentable获取导航控制器,监听栈变化:

struct NavigationStackObserver: UIViewControllerRepresentable {
    var onStackChange: (Int) -> Void
    
    func makeUIViewController(context: Context) -> UIViewController {
        UIViewController()
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        guard let navController = uiViewController.navigationController else { return }
        context.coordinator.navController = navController
        onStackChange(navController.viewControllers.count)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(onStackChange: onStackChange)
    }
    
    class Coordinator: NSObject, UINavigationControllerDelegate {
        var onStackChange: (Int) -> Void
        weak var navController: UINavigationController?
        
        init(onStackChange: @escaping (Int) -> Void) {
            self.onStackChange = onStackChange
            super.init()
        }
        
        func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
            onStackChange(navigationController.viewControllers.count)
        }
    }
}

// 使用示例
struct ContentView: View {
    @State private var navStackCount = 1
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("页面1", destination: Text("页面1"))
                NavigationLink("页面2", destination: Text("页面2"))
                // 更多NavigationLink...
            }
            .background(NavigationStackObserver { count in
                navStackCount = count
            })
            .toolbar {
                Button("是否有激活链接?") {
                    let hasActiveLink = navStackCount > 1
                    print(hasActiveLink)
                }
            }
        }
    }
}

此方案无需给每个NavigationLink加监听,自动跟踪整个导航栈变化,只要栈内控制器数量大于1(根控制器为第一个),就说明存在激活的链接。

总结

  • iOS16+优先使用NavigationStack + NavigationPath,简洁高效,无需手动管理单个链接状态。
  • 旧版本推荐UIKit导航控制器代理方案,一次性监听全局导航栈,避免重复绑定isActive。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:31:34