SwiftUI中AddBuyerView点击按钮无法返回根视图BuyersView的问题求助
你好,我看了你的代码后发现问题所在:你当前使用的NavigationLink并没有和NavigationStack绑定的path联动,导致跳转AddBuyerView时根本没把路由信息写入path,所以后续清空path的操作完全无效(这就是为什么path一直显示0的原因)。
问题根源拆解
你用的是NavigationLink("Click Item", destination: ...)这种传统写法,它属于独立的导航逻辑,不会更新NavigationStack绑定的path变量。只有当你使用基于path的导航方式(NavigationLink(value: ...)配合navigationDestination)时,跳转动作才会把对应的路由信息加入到path中,这时清空path才能触发返回根视图的操作。
解决方案步骤
1. 定义路由枚举(规范做法,可选但推荐)
先在BuyersView外部定义一个枚举,用来标识不同的导航页面,同时可以携带需要传递的参数:
enum BuyerRoute: Hashable { case addBuyer([Category]) }
2. 修改BuyersView的导航逻辑
把原来的NavigationLink改成基于value的形式,同时添加navigationDestination来处理路由跳转:
struct BuyersView: View { @State private var path = NavigationPath() @State var currentFase : Category = .init(title: "All Buyers") let fases: [Category] = [ .init(title: "All Buyers"), .init(title: "Nieuw"), .init(title: "Email contact"), .init(title: "Gesproken"), .init(title: "Gepland"), .init(title: "Bezocht"), .init(title: "Bod"), .init(title: "Sale"), .init(title: "Zoekt niet meer") ] // 修正:把allbuyers改为计算属性,@State变量不能放在body内部 var allbuyers: [Buyer] { // 这里的Buyer是你的数据模型,根据实际情况调整 getAllBuyers(currentfase: currentFase) } var body: some View { NavigationStack(path: $path){ VStack{ CategoryView(categories: fases, currentSelection: $currentFase) HStack{ Spacer() // 改成基于value的NavigationLink NavigationLink(value: BuyerRoute.addBuyer(fases)) { Text("Click Item") } } BuyersPerFaseView(buyers: $allbuyers) } // 添加navigationDestination处理路由跳转 .navigationDestination(for: BuyerRoute.self) { route in switch route { case .addBuyer(let fases): AddBuyerView(path: $path, fases: fases) } } } } }
3. 验证AddBuyerView的按钮逻辑
你原来的按钮代码其实没问题,只要path被正确绑定且路由跳转时更新了path,点击按钮清空path就会生效:
Button("test") { print(path.count) // 现在这里会输出1(跳转后path里有一条路由记录) path = NavigationPath() print(path.count) // 输出0,同时页面会自动返回根视图 }
另外补充一个小细节:你原来在BuyersView的body里直接声明@State var allbuyers = getAllBuyers(currentfase: currentFase)是错误的,@State变量不能放在body内部,所以改成计算属性后,每次currentFase变化时,allbuyers会自动重新计算更新。
这样修改后,点击test按钮就能正常返回根视图了。
备注:内容来源于stack exchange,提问作者Tessa Limbeek

