SwiftUI中navigationDestination:isPresented视图始终居栈顶是否为预期行为?
问题现象
当通过navigationDestination(isPresented:)将视图推入导航栈后,即便后续通过navigationDestination(for:)推入其他视图,前者始终处于栈顶,具体表现为:
- 点击页面1的按钮推入页面2;
- 点击页面2上的
NavigationLink试图推入页面3时,页面2仍停留在栈顶显示,返回时才会看到页面3; - 推入页面3后导航栈结构为:
['page 1', 'page 3', 'page 2'];再次点击链接后栈结构变为:['page 1', 'page 3', 'page 3', 'page 2']。
代码示例
struct ContentView: View { @State var navigateToSecondPage = false var body: some View { NavigationStack { VStack { Text("1st page") Button("Navigate to 2nd page") { navigateToSecondPage = true } } .navigationDestination(isPresented: $navigateToSecondPage) { VStack { Text("2nd page") NavigationLink(value: SomeItem()) { Text("Navigate to 3rd page") } } } .navigationDestination(for: SomeItem.self) { item in Text("3rd page") } } } } struct SomeItem: Hashable { }
结论:该现象符合预期
原因在于navigationDestination(isPresented:)的工作机制:
- 绑定的状态值
navigateToSecondPage为true时,导航系统会持续确保对应的页面(页面2)存在于栈顶; - 当通过基于值的
NavigationLink推入页面3时,页面3确实被加入栈,但因为navigateToSecondPage仍为true,系统会立即将页面2重新推到栈顶,导致页面2保持显示,页面3被压在其下方; - 点击返回按钮时,页面2被弹出,此时
navigateToSecondPage会被自动设为false,之前推入的页面3就会显示出来。
解决方法
如果需要正常的栈导航逻辑,可通过以下方式调整:
- 在推入页面3时手动将
navigateToSecondPage设为false,修改页面2的NavigationLink:
NavigationLink(value: SomeItem()) { Text("Navigate to 3rd page") } .onTapGesture { navigateToSecondPage = false }
- 统一使用基于值的导航方式,将页面2的推入也改为
navigationDestination(for:)实现,避免混合两种导航触发方式。
内容的提问来源于stack exchange,提问作者kluver
相关产品推荐
相关产品推荐

