关于 iOS 开发者来说,导航视图无疑是最常用的组件之一。当 SwiftUI 首次发布时,官方提供了 NavigationView
视图,以供开发人员构建根据导航的用户界面。
跟着 iOS16 的发布,NavigationView
现已被苹果官方弃用,并引入了一个名为 NavigationStack
的新视图来出现视图仓库。最重要的是,开发者能够利用这个新视图来构建数据驱动的导航。
NavigationView 的运用办法
在 iOS16 之前,咱们能够运用 NavigationView 加 NavigationLink 来进行导航栏的显现以及导航跳转:
var body: some View {
NavigationView {
NavigationLink {
Text("概况页")
} label: {
Text("去概况")
}
}
}
上述代码创建了一个带有导航控制器的视图,而且带有《去概况》的一个按钮。点击该按钮能够导航到概况页面。
NavigationStack 的运用办法
运用 NavigationStack 在根视图上显现视图仓库。用户能够通过点击 NavigationLink
将视图添加到视图栈的顶部,或许运用撤退按钮或滑动手势来删去视图。
视图栈总是显现栈顶的视图,而且根视图是不能被删去的。
咱们能够运用 navigationDestination(for:destination:)
修饰符将视图与相关联的数据进行绑定,然后初始化一个 NavigationLink 来进行导航跳转。
假定咱们要实现这样一个需求:主页显现猫咪的列表,点击每一条会跳转到概况页。
首要,定义一个结构体用来存储猫咪的数据:
struct Cat: Identifiable, Hashable {
let name: String
let id: UUID
}
由于 List 对每一条数据要求唯一性,所以咱们的结构体要恪守上述的两个协议。
接着,创建一个名为 CatDetailView
的视图来表示概况页,编写以下代码:
struct CatDetailView: View {
let cat: Cat
var body: some View {
Text(cat.name)
}
}
最后,便是创建一个名为 CatListView
的视图,用来表示列表页,编写以下代码:
struct CatListView: View {
let cats = [Cat(name: "red cat", id: UUID()),
Cat(name: "black cat", id: UUID()),
Cat(name: "orange cat", id: UUID())]
var body: some View {
NavigationStack {
List(cats) { cat in
NavigationLink(cat.name, value: cat)
}
.navigationDestination(for: Cat.self) { cat in
CatDetailView(cat: cat)
}
}
}
}
效果图如下:
多个 Navigation Destination 修饰符
开发者能够定义多个 navigationDestination
修饰符来处理不同类型的导航链接。在前面的比方中咱们处理了类型为 Cat 的导航处理。假定咱们需要在主页加一种类型为 Dog 的导航处理,能够直接在后面再加一个 navigationDestination
。比方下面的代码:
NavigationStack {
List(cats) { cat in
NavigationLink(cat.name, value: cat)
}
List(dogs) { dog in
NavigationLink(dog.name, value: dog)
}
.navigationDestination(for: Cat.self) { cat in
CatDetailView(cat: cat)
}
.navigationDestination(for: Dog.self) { dog in
DogDetailView(dog: dog)
}
}
Tips: DogDetailView 与 Dog 皆与猫咪的类似,仅改动一下名字。冗余代码就不在此贴出了。
导航栏的状况管理
与之前的 NavigationView 不同,新的 NavigationStack 能够方便地盯梢导航状况。NavigationStack 视图有另一个初始化办法,它接受一个path参数,该参数绑定到仓库的导航状况:
public init(path: Binding<Data>, @ViewBuilder root: () -> Root)
示例代码如下:
@State private var presentedCats: [Cat] = []
var body: some View {
NavigationStack(path: $presentedCats) {
List(cats) { cat in
NavigationLink(cat.name, value: cat)
}
.navigationDestination(for: Cat.self) { cat in
VStack {
Text("\(presentedCats.count), \(presentedCats.description)")
CatDetailView(cat: cat)
}
}
}
}
首要声明了一个 State 的属性用来保存当时导航的状况,然后在 NavigationStack 的初始化办法中将其传递进去即可。