SwiftUI NavigationStack问题:NavigationPath的path.count为何显示错误?
问题重现
在iOS 16的SwiftUI环境中使用NavigationStack,点击子页面的返回按钮回到根页面时,根视图onAppear中打印的path.count为1,而非预期的0。
原因分析
这是因为onAppear的触发时机早于NavigationStack对path的更新。当从子页面返回时,根视图的onAppear会先执行,此时path还没来得及被系统清空,所以打印出的是返回前的path.count值(也就是1)。
修复方案
方案1:监听path的变化替代onAppear
如果需要跟踪path的实际长度,不要依赖onAppear,而是通过onChange(of: path)来监听path的实时变化,这样能获取到最新的path.count:
struct ContentView: View { var settingsLink: [SettingsLink] = [.init(name: "Settings")] var notificationsLink: [NotificationsLink] = [.init(name: "Notifications")] @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { VStack { NavigationLink(value: settingsLink[0]) { Text(settingsLink[0].name) } NavigationLink(value: notificationsLink[0]) { Text(notificationsLink[0].name) } } // 替换onAppear为onChange监听path .onChange(of: path) { newPath in print("Root Path Count: \(newPath.count)") } .navigationDestination(for: SettingsLink.self) { settingsLink in VStack { Text("\(settingsLink.name)") } .onAppear() { print("Settings: \(path.count)") } } .navigationDestination(for: NotificationsLink.self) { notificationsLink in VStack { Text("\(notificationsLink.name)") } .onAppear() { print("Notifications: \(path.count)") } } } } }
方案2:使用task视图修饰符(可选)
如果确实需要在根视图出现时获取正确的path.count,可以使用task修饰符,它会在视图出现后稍晚执行,能等待path完成更新:
// 替换原来的onAppear .task { print("Root Path Count: \(path.count)") }
方案3:自定义返回按钮(手动控制path)
如果需要完全掌控返回行为,可以隐藏系统返回按钮,自定义返回按钮并手动更新path:
.navigationDestination(for: SettingsLink.self) { settingsLink in VStack { Text("\(settingsLink.name)") } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("返回") { path.removeLast() // 或直接path = NavigationPath()清空整个路径 } } } .onAppear() { print("Settings: \(path.count)") } }
验证效果
使用方案1的onChange监听后,返回根页面时会打印出Root Path Count: 0,符合预期。
内容的提问来源于stack exchange,提问作者Pro Girl
相关产品推荐
相关产品推荐

