NavigationView:基础,SwiftUI 应用中的导航堆栈

作者: IT Sectr 发布日期: 2026-02-22 阅读时间: 6 分钟

NavigationView — 一个 SwiftUI 容器组件,用于组织屏幕之间的堆栈导航。NavigationView 创建带有自动导航栏、标题和「返回」按钮的导航堆栈。从 iOS 16 开始,Apple 建议使用 NavigationStack。更多内容请阅读 Apple 文档

要点

  • NavigationView — 用于堆栈导航的 SwiftUI 容器,创建导航栏和返回按钮
  • NavigationLink — 在 NavigationView 内切换到新屏幕的元素
  • NavigationStack — NavigationView 的继任者(iOS 16+),支持程序化堆栈管理
  • .toolbar — 用于向导航栏添加按钮的修饰符
  • .navigationTitle — 以 large 或 inline 样式设置屏幕标题

什么是 NavigationView?

NavigationView — 一个 SwiftUI 容器,它包裹屏幕层次结构并提供导航界面。在 NavigationView 内部运行着 NavigationLink——一个点击后会用新屏幕替换当前屏幕的元素。NavigationView 自动添加带有标题和「返回」按钮的导航栏。

NavigationView 与 SwiftUI 一起在 iOS 13 中出现。从概念上讲,它取代了 UIKit 中的 UINavigationController,但以声明方式实现。开发人员通过 NavigationLink 描述屏幕之间的连接,而不是手动 push/pop。系统自动管理堆栈。

NavigationView 支持 .navigationTitle、.navigationBarTitleDisplayMode、.toolbar 和 .searchable 修饰符。对于 iOS 16+,Apple 引入了 NavigationStack,它保留了 NavigationView 的 API,但通过 NavigationPath 增加了程序化堆栈管理。对于支持 iOS 15 及更早版本的项目,NavigationView 仍然是唯一的选择。

NavigationLink — 一个 SwiftUI 元素,在 NavigationView 或 NavigationStack 内创建到目标屏幕的跳转。点击 NavigationLink 后,系统将目标屏幕添加到导航堆栈。跳转动画——iOS 标准从右侧 push,根据平台进行调整。

swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            List(items) { item in
                NavigationLink(destination: DetailView(item: item)) {
                    Text(item.title)
                }
            }
            .navigationTitle("列表")
        }
    }
}

struct DetailView: View {
    let item: Item

    var body: some View {
        VStack {
            Text(item.description)
                .navigationTitle(item.title)
                .navigationBarTitleDisplayMode(.inline)
        }
    }
}

NavigationLink 接受两个参数:destination — 目标 View,和 label — 用户点击的元素。对于列表,使用 value 和 NavigationLink(value:) 的语法很方便,它会自动取消选择单元格并与 NavigationPath 配合使用。

从 iOS 16 开始,Apple 推出了 NavigationStack 作为 NavigationView 的替代品。NavigationStack 保留了声明式语法,但增加了一个关键能力——通过 NavigationPath 类型的 path 属性或 Hashable 数组进行程序化堆栈管理。

功能NavigationView (iOS 13-15)NavigationStack (iOS 16+)
程序化 push无,仅通过 NavigationLink有,通过 path.append(value)
popToRoot仅 dismiss 到 rootpath.removeLast(path.count)
深层链接实现复杂通过 path 内置支持
堆栈类型化无(destination 中任意 View)有(Hashable 值数组)
iPad SplitViewColumnStyle / StackStyleNavigationSplitView (iOS 16+)

对于最低版本为 iOS 16+ 的项目,使用 NavigationStack。对于支持 iOS 14-15 的项目——使用 NavigationView。NavigationStack 没有适用于旧版本的直接替代品,因此升级需要检查兼容性。

Toolbar 和 navigationTitle 配置

.toolbar.navigationTitle 修饰符管理导航栏的内容。.navigationTitle 设置屏幕标题,.navigationBarTitleDisplayMode 选择样式:.large(大标题,默认)或 .inline(紧凑型,如设置应用中)。.toolbar 添加按钮、搜索和分段控制。

swift
struct SettingsView: View {
    var body: some View {
        NavigationStack {
            Form {
                Section("个人资料") {
                    Text("用户名")
                    Toggle("通知", isOn: $notifications)
                }
            }
            .navigationTitle("设置")
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("保存") { save() }
                }
                ToolbarItem(placement: .navigationBarLeading) {
                    EditButton()
                }
            }
        }
    }
}

.searchable — 另一个将搜索栏集成到导航栏的修饰符。可与 NavigationView 和 NavigationStack 配合使用。搜索在滚动时自动隐藏,向下滑动时显示。支持通过 Binding String 进行列表过滤。

使用 NavigationPath 进行程序化导航

NavigationPath — iOS 16+ 的类型,将导航堆栈表示为 Hashable 值的集合。开发人员向 path 添加元素以进行程序化跳转,删除元素以返回。NavigationPath 支持深层链接、推送通知和状态恢复。

swift
struct AppNavigation: View {
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            List(categories) { category in
                NavigationLink("分类 \(category.name)",
                               value: category)
            }
            .navigationTitle("分类")
            .navigationDestination(for: Category.self) { category in
                ProductListView(category: category)
            }
            .navigationDestination(for: Product.self) { product in
                ProductDetailView(product: product)
            }
        }

        // 通过深层链接的程序化跳转
        .onOpenURL { url in
            guard let productId = DeepLinkParser.parse(url) else { return }
            path.append(Product(id: productId))
        }
    }
}

.navigationDestination(for:) 注册需要显示屏幕的数据类型。当该类型的值添加到 path 时,系统会自动创建目标 View。这种方法取代了显式的 NavigationLink(destination:),使导航严格类型化。

NavigationView 和 NavigationStack 在所有 Apple 平台上运行:iOS、iPadOS、watchOS、tvOS 和 macOS。行为会适应屏幕。在 iPad 上,NavigationStack 支持 NavigationSplitView,它取代了 UIKit 中的 UISplitViewController,在宽屏上显示两列。

NavigationSplitView(iOS 16+)将屏幕分为侧边栏(列表)和详情(详细信息)。在 iPhone 上,侧边栏隐藏,仅通过 NavigationLink 显示详情。在 iPad 上,侧边栏和详情在分屏模式下同时显示。

swift
struct AdaptiveNavigation: View {
    @State private var selectedCategory: Category?

    var body: some View {
        NavigationSplitView {
            List(categories, selection: $selectedCategory) { category in
                Text(category.name)
            }
            .navigationTitle("分类")
        } detail: {
            ProductListView(category: selectedCategory)
        }
    }
}

NavigationSplitView 自动为每个设备选择最佳显示模式。在 iPhone 竖屏模式下——堆栈,在 iPad 和 iPhone 横屏模式下——分屏。开发人员无需为不同的 size class 编写单独的代码。

常见问题

NavigationView 和 NavigationStack 有什么区别?

NavigationView — 旧 API(iOS 13-15),仅支持声明式 NavigationLink。NavigationStack — 新 API(iOS 16+),添加了用于程序化导航、深层链接和严格类型化堆栈的 path。Apple 建议新项目使用 NavigationStack。

如何向 navigationBar 添加按钮?

通过 .toolbar 修饰符和 ToolbarItem。例如:.toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('设置') { } } }。Placement 决定位置:trailing(右侧)、leading(左侧)、principal(中间)。

如何设置标题及其样式?

标题通过 .navigationTitle('名称') 设置。样式 —— .navigationBarTitleDisplayMode(.large) 或 .inline。Large —— iOS Music 风格的大标题,inline —— 紧凑型,如设置应用中。每个屏幕可以单独更改样式。

如何通过 NavigationLink 传递数据?

三种方式:通过 value(NavigationLink(value:item) { Label }, iOS 16+),通过 destination + label,通过 isActive 进行程序化跳转。带 value 的 NavigationLink 对于列表更简洁,因为不需要在跳转前创建目标 View。

可以在 watchOS 和 tvOS 上使用 NavigationView 吗?

可以。NavigationView 和 NavigationStack 适用于 iOS、iPadOS、watchOS、tvOS 和 macOS。在 watchOS 上,导航使用带有 Digital Crown 滚轮的界面层次结构;在 tvOS 上,使用遥控器的焦点输入。行为会自动适应平台。

总结

  • NavigationView — 用于堆栈导航的 SwiftUI 容器,带有自动导航栏和「返回」按钮
  • NavigationLink — 主要跳转元素,支持声明式(destination)和基于 value 的语法
  • NavigationStack(iOS 16+)取代 NavigationView,通过 NavigationPath 添加程序化堆栈管理
  • .toolbar 向导航栏添加按钮,.navigationTitle 设置标题并支持 large/inline 样式选择
  • NavigationPath — 用于程序化导航和深层链接的严格类型化 Hashable 值堆栈
  • NavigationSplitView(iOS 16+)适应 iPad 和 iPhone 的界面,自动选择分屏或堆栈
  • NavigationView 和 NavigationStack 之间的选择由项目中支持的最低 iOS 版本决定

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读