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

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就会显示出来。

解决方法

如果需要正常的栈导航逻辑,可通过以下方式调整:

  1. 在推入页面3时手动将navigateToSecondPage设为false,修改页面2的NavigationLink:
NavigationLink(value: SomeItem()) {
    Text("Navigate to 3rd page")
}
.onTapGesture {
    navigateToSecondPage = false
}
  1. 统一使用基于值的导航方式,将页面2的推入也改为navigationDestination(for:)实现,避免混合两种导航触发方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:45:57