上一节我们介绍了 SwiftUI 的列表(List
)视图,ForEach
和Identifiable
协议。
这一节我们将详细介绍在 SwiftUI 中如何使用 NavigationView(iOS 16 前)和 NavigationStack(iOS 16 及更高版本)
来构建导航界面,同时探讨如何自定义导航栏的外观、返回按钮,以及使用 SwiftUI 提供的 toolbar
等高级用法。
在 iOS 应用开发中,导航界面是非常常见且重要的部分。无论是显示一系列数据还是管理不同的功能模块,
都少不了使用导航栏和导航视图来为用户提供分层次的浏览体验。
本文将详细介绍在 SwiftUI 中如何使用 NavigationView(iOS 16 前)和 NavigationStack(iOS 16 及更高版本)
来构建导航界面,同时探讨如何自定义导航栏的外观、返回按钮,以及使用 SwiftUI 提供的 toolbar
等高级用法。
目录
- 导航界面简介
- 使用 NavigationStack 搭建导航视图
- 为导航视图添加标题
- 使用 NavigationLink 传递数据到详情视图
- 自定义导航栏外观
- 隐藏系统返回按钮并自定义返回按钮
- 实战案例:餐馆列表与详情视图
- 实战案例:文章列表与详情视图
- 总结
- 完整示例代码
导航界面简介
在绝大多数 iOS 应用中,用户都会和一个带有导航栏和列表的界面进行交互,通过点击列表项进入详情视图,再通过返回按钮回到上一级页面。在 SwiftUI 中,这种交互可以通过以下组件来完成:
- NavigationView(在 iOS 16 之前使用)
- NavigationStack(在 iOS 16 及更高版本中建议使用)
- NavigationLink(用于在列表或其他视图中触发导航行为)
- NavigationTitle / navigationBarTitle / toolbar 等修饰器,用于定制导航栏外观和功能
使用 NavigationStack 搭建导航视图
在 iOS 16(或更新版本)中,Apple 引入了新的 NavigationStack 组件来取代原有的 NavigationView
。虽然 NavigationView
目前仍然可用,但建议使用 NavigationStack
以获得更好的未来兼容性。使用方式非常类似:
NavigationStack {
List {
ForEach(restaurants) { restaurant in
BasicImageRow(restaurant: restaurant)
}
}
.listStyle(.plain)
}
如果你在较早版本的 iOS 中使用 SwiftUI,可以使用:
NavigationView {
List {
ForEach(restaurants) { restaurant in
BasicImageRow(restaurant: restaurant)
}
}
.listStyle(.plain)
}
为导航视图添加标题
在 SwiftUI 中,可以使用修饰器 navigationTitle
(或 navigationBarTitle
)为导航栏添加标题,比如:
NavigationStack {
List {
ForEach(restaurants) { restaurant in
BasicImageRow(restaurant: restaurant)
}
}
.listStyle(.plain)
.navigationTitle("Restaurants")
}
这样就可以为导航界面设置一个大标题(Large Title)。如果你希望在界面中展示小标题,可以使用 设置大标题还是小标题 章节所述的方法来自定义显示模式。
使用 NavigationLink 传递数据到详情视图
在实际项目中,我们通常需要在点击列表项后跳转到详情视图,展示更详细的信息。SwiftUI 提供了 NavigationLink
来实现这一功能。
举例来说,如果我们有一个 RestaurantDetailView
视图需要接收 restaurant
参数,可以这样做:
List {
ForEach(restaurants) { restaurant in
NavigationLink(destination: RestaurantDetailView(restaurant: restaurant)) {
BasicImageRow(restaurant: restaurant)
}
}
}
.listStyle(.plain)
当用户点击列表中的某一行时,应用就会通过 NavigationLink
把对应的 restaurant
对象传递给详情视图进行渲染。
自定义导航栏外观
设置大标题还是小标题
在 SwiftUI 中,如果你想让导航栏以大标题的形式显示,可以使用 .navigationBarTitleDisplayMode(.automatic)
或者在 iOS 较早版本使用 .largeNavigationBarTitle
。如果你想要小标题,则可以使用:
.navigationBarTitleDisplayMode(.inline)
.inline