NavigationStack 是 SwiftUI 在 iOS 16/macOS 13 引入的新一代导航容器,算是对老的 NavigationView的替代品。它背后的设计哲学和用法变化挺大,尤其是更接近 UIKit 里的 UINavigationController 或 AppKit 的导航逻辑。
基本作用
它的核心作用和 NavigationView 类似:在多个视图之间建立层级式(栈式)的导航关系。但它提供了更强的控制能力,可以直接操作导航栈(stack)的内容,而不仅仅是 “点一个 link → push 一个页面”。
基本用法
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("去详情页 1") {
DetailView(text: "这是详情页 1")
}
NavigationLink("去详情页 2") {
DetailView(text: "这是详情页 2")
}
}
.navigationTitle("首页")
}
}
}
struct DetailView: View {
let text: String
var body: some View {
Text(text)
.navigationTitle("详情")
.navigationBarTitleDisplayMode(.inline)
}
}
NavigationStack 是最外层容器。
NavigationLink 用来跳转到下一个视图。
.navigationTitle() 设置导航栏标题。
.navigationBarTitleDisplayMode(.inline) 可以控制标题样式(大标题 / 小标题)。


核心特点
1、显式栈管理
以前 NavigationView 下只能用 NavigationLink 隐式 push/pop。
NavigationStack 提供了一个 path 属性(通常绑定到一个 @State 数组),你可以直接操作这个数组,控制导航栈里的所有页面。
@State private var path: [String] = []
var body: some View {
NavigationStack(path: $path) {
List {
Button("跳到详情 A") {
path.append("A")
}
Button("跳到详情 B") {
path.append("B")
}
}
.navigationDestination(for: String.self) { value in
Text("这是详情页 \(value)")
}
}
}
在这里,path 就是栈,你追加元素就是 push,移除就是 pop。
2、navigationDestination 的解耦
不需要像 NavigationLink 那样直接在写按钮时就塞入目标视图。
可以统一声明:对于某种类型的数据(比如 String、User、Article),跳转到哪个视图。
这样做更符合数据驱动的思维,也让代码更清晰。
3、更灵活的深层导航
可以一次性把 path 设置为 [“A”, “B”, “C”],直接跳转到三级页面,适合深层连接。
这在旧的 NavigationView 里几乎是不可能的。
4、和老的 NavigationView 区别
NavigationView 更像是“外壳 + 隐式 push/pop”,很多状态不透明(比如很难恢复栈状态)。
NavigationStack 更像“栈的真实数据模型”,你可以完全掌控和恢复。
Apple 也明确表示:新项目尽量用 NavigationStack,旧项目慢慢迁移。
使用 path 手动控制导航栈
除了用 NavigationLink 自动跳转,还可以自己控制导航栈。
struct ContentView: View {
@State private var path: [String] = []
var body: some View {
NavigationStack(path: $path) {
List {
Button("跳到详情 A") {
path.append("A")
}
Button("跳到详情 B") {
path.append("B")
}
}
.navigationTitle("首页")
.navigationDestination(for: String.self) { value in
DetailView(text: "详情 \(value)")
}
}
}
}
struct DetailView: View {
let text: String
var body: some View {
Text(text)
.navigationTitle(text)
}
}
@State private var path: [String] 表示当前的导航路径。
.navigationDestination(for:) 告诉 NavigationStack 当遇到某种类型时应该跳转到哪个视图。
手动 path.append(…) 可以模拟 push,path.removeLast() 可以模拟 pop。
常见配合的修饰符
.navigationTitle(“标题”),设置标题。
.navigationBarTitleDisplayMode(.inline / .large),标题样式。
.toolbar { … },添加按钮、菜单。
.toolbar(.hidden, for: .navigationBar),隐藏导航栏。
.navigationDestination(for: Type.self),指定不同数据类型对应的目标视图。
总结
NavigationStack 是 SwiftUI 里“可控导航”的新时代武器:它让导航变成了一个数据问题,而不是一个 UI Hack。
toolbar、navigationTitle等修饰符都依赖导航容器使用。
扩展文章
1、SwiftUI导航栏标题navigationTitle:https://fangjunyu.com/2025/09/12/swiftui%e5%af%bc%e8%88%aa%e6%a0%8f%e6%a0%87%e9%a2%98navigationtitle/
2、SwiftUI在iOS中的toolbar工具栏:https://fangjunyu.com/2024/12/07/swift-toolbar%e5%b7%a5%e5%85%b7%e6%a0%8f/
3、SwiftUI导航视图控件NavigationLink:https://fangjunyu.com/2024/12/11/swiftui%e5%af%bc%e8%88%aa%e8%a7%86%e5%9b%be%e6%8e%a7%e4%bb%b6navigationlink/
4、Swift删除NavigationLink自带的颜色效果:https://fangjunyu.com/2024/10/27/swift%e5%88%a0%e9%99%a4navigationlink%e8%87%aa%e5%b8%a6%e7%9a%84%e9%a2%9c%e8%89%b2%e6%95%88%e6%9e%9c/
5、SwiftUI隐藏NavigationLink视图的返回按钮:https://fangjunyu.com/2025/03/13/swiftui%e9%9a%90%e8%97%8fnavigationlink%e8%a7%86%e5%9b%be%e7%9a%84%e8%bf%94%e5%9b%9e%e6%8c%89%e9%92%ae/
6、SwiftUI请求评分requestReview和NavigationLink冲突问题:https://fangjunyu.com/2025/02/27/swiftui%e8%af%b7%e6%b1%82%e8%af%84%e5%88%86requestreview%e5%92%8cnavigationlink%e5%86%b2%e7%aa%81%e9%97%ae%e9%a2%98/
7、SwiftUI在TabView中使用NavigationLink跳转失败的问题:https://fangjunyu.com/2025/05/09/swiftui%e5%9c%a8tabview%e4%b8%ad%e4%bd%bf%e7%94%a8navigationlink%e8%b7%b3%e8%bd%ac%e5%a4%b1%e8%b4%a5%e7%9a%84%e9%97%ae%e9%a2%98/
8、Xcode报错:A NavigationLink is presenting a value of type “Int” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated. https://fangjunyu.com/2024/11/24/xcode%e6%8a%a5%e9%94%99%ef%bc%9aa-navigationlink-is-presenting-a-value-of-type-int-but-there-is-no-matching-navigationdestination-declaration-visible-from-the-location-of-the-link-t/
9、SwiftUI配置深层链接:https://fangjunyu.com/2025/02/08/swiftui%e9%85%8d%e7%bd%ae%e6%b7%b1%e5%b1%82%e9%93%be%e6%8e%a5/
10、SwiftUI导航NavigationView:https://fangjunyu.com/2025/09/12/swiftui%e5%af%bc%e8%88%aanavigationview/