SwiftUI NavigationStack 的替代方案。NavigationRouter 在利用 NavigationStack 提升性能的同时,还能更好地控制导航。它还提供了简便的编程式导航方法。NavigationRouter 是类型安全的,并且避免使用 AnyView 以尽可能提高性能。
Swift Package Manager 是一种用于自动化 Swift 代码分发的工具,并且集成到 Swift 编译器中。
要将 SwiftUI-Navigation-Router 添加到你的项目中,请执行以下操作。
File -> Add Packages
NavigationRouter
是一个视图,用于替代 NavigationStack
。它模拟了 NavigationStack
的所有功能,并在许多方面增加了灵活性。为了使用它,我们首先需要导入 NavigationRouter
模块。
import SwiftUI
import NavigationRouter
然后,你可以替换当前的 NavigationStack
,或者(如果在新项目中)将 NavigationRouter
放在你的根视图中。 像这样
struct RootView: View {
var body: some View {
NavigationRouter {
HomeView()
}
}
}
为了导航到不同的视图,NavigationRouter
需要知道哪些视图是可导航的。你可以使用 routerDestinations
ViewModifier
轻松地做到这一点。 你可以将它们全部添加到你的根视图中,或者沿路线指定它们。 这是前者的演示。
struct RootView: View {
var body: some View {
NavigationRouter {
HomeView()
.routerDestinations(ViewTwo.self, ViewThree.self)
.routerDestinations(ViewFour.self)
}
}
}
添加了 NavigationRouter
并添加了你的 Navigable Views
之后。 你可以开始导航了。 向前导航 / 推送视图非常简单! 你可以使用 PushView
,或者使用 @NavRouter
属性包装器访问 Router
,然后调用 push
函数。
使用 PushView
是向前导航的最简单方法。 在你需要导航的任何文件中,导入 NavigationRouter
,然后就像使用 NavigationLink
一样简单。 可以使用 String
或自定义标签 View
创建 PushView
。
注意:PushView
的功能类似于 NavigationLink
的 Button
注意:PushView
是 NavigationLink
的替代品,在 NavigationRouter
中使用 NavigationLink
会导致断言失败
struct ViewOne: View {
var body: some View {
VStack {
// Using a Text for its View.
PushView("Navigate to View Two", destination: ViewTwo())
// Or
// Using a Custom Label for its View.
PushView(ViewTwo()) {
// Custom Label View.
Image("MyNavigationImage")
}
}
}
}
使用 Navigation Router 进行编程式导航几乎与使用 PushView
一样简单。 我们只需要一个额外的步骤。 我们需要手动访问我们的 Router
。 我们可以使用 @NavRouter
属性包装器来实现。
struct ViewOne: View {
// You can name this variable whatever, router is what we will use for these examples.
@NavRouter var router
var body: some View {
// View Body...
}
}
现在我们可以访问我们的 Router
,我们可以用它来导航。 要推送一个视图,就像调用 push
函数一样简单。 通常你可能会在 Button
或 onTapGesture
中执行此操作; 但是,你可以在需要它的任何地方调用它,这就是使用编程式导航的魅力所在。
var body: some View {
Button("Navigate To View Two") {
router.push(ViewTwo())
}
}
使用编程式导航时,我们可以使用 push
函数的附加参数。 此参数是一个 [String : Any]
字典。 这使你可以将一些附加信息绑定到你的 View
以用于特定目的。
router.push(ViewTwo(), with: ["name" : "View Two", "totalViews" : 6])
SwiftUI 的 NavigationStack
提供了非常有限的向后导航。 你可以返回一次、返回一定的次数或返回到根目录。 但是导航并不总是那么简单。 通常你可能不知道你需要返回多少次,或者你想返回到特定的视图,或者可能为用户提供一种查看他们可以返回的所有不同位置的方法。 这就是 SwiftUI-Navigation-Router 的用武之地。 Router
提供了许多向后导航的方法,无论是编程式的还是使用 PopView
。
默认情况下,SwiftUI 的 NavigationStack
中未包含的向后导航方式示例包括
View
,弹出一定数量的 Views
,如果你尝试向后导航太远。View
匹配的最后一个 View
。Array
以进行导航,并轻松地导航回它们。View
。可以使用 PopView
或编程式地使用 Router
完成上述所有操作,包括 SwiftUI 的 NavigationStack
中已经包含的内容。
使用 PopView
是向后导航的最简单方法。 在你需要从其向后导航的任何文件中,导入 NavigationRouter
,然后就像使用 NavigationLink
一样简单。 可以使用 String
或自定义标签 View
创建 PopView
。
注意:PopView
的功能类似于 NavigationLink
的 Button
struct ViewTwo: View {
var body: some View {
VStack {
// Using a Text for its View.
PopView("Go Back One View")
// Or
// Using a Custom Label for its View.
PopView {
// Custom Label View.
Image("BackOneViewImage")
}
}
}
}
PopView
还支持导航回多个级别,你可以指定要返回的数量。
PopView("Go Back Two Views", amount: 2)
// or
PopView(2) {
Image("BackTwoViewsImage")
}
最后,PopView
还支持上述所有高级导航。 通过将数量替换为 PopType
。 wiki 中将对这些不同的 PopTypes
进行完整描述。 但这是一个关于如何实现它以返回到根视图的示例。
PopView("Back To Root", popType: .root)
// or
PopView(.root) {
Image("BackToRootImage")
}
使用 Navigation Router 进行编程式导航几乎与使用 PopView
一样简单。 我们只需要一个额外的步骤。 我们需要手动访问我们的 Router
。 我们可以使用 @NavRouter
属性包装器来实现。
struct ViewTwo: View {
// You can name this variable whatever, router is what we will use for these examples.
@NavRouter var router
var body: some View {
// View Body...
}
}
现在我们可以访问我们的 Router
,我们可以用它来导航。 要弹出一个视图,你只需要调用其中一个 pop
函数。 通常你可能想在 Button
或 onTapGesture
中执行此操作; 但是,只要你有权访问 Router
,就可以在需要的任何地方调用它。
var body: some View {
Button("Navigate Back One View") {
router.pop()
}
}
你还可以指定要返回多个 Views
,方法是将数字传递到 pop
函数中。
// Pops Back 2 Views
router.pop(2)
与 PopView 类似,你可以访问上面提到的所有高级导航方法。 你可以在应用程序文档或 Wiki 中找到这些方法。