SwiftUI 页面导航最佳实践
通过全局 Router
- 定义一个全局 Router 对象,维护页面跳转类型和参数。
@Observable
final class Router {
public enum Destination: Codable, Hashable {
case pageA(models: [Model])
case pageB
}
var navPath = NavigationPath()
func navigate(to destination: Destination) {
navPath.append(destination)
}
func navigateBack() {
navPath.removeLast()
}
func navigateToRoot() {
navPath.removeLast(navPath.count)
}
}
枚举 Destination
可以指定要跳转到哪个页面以及携带的参数。
- 将 Router 和 NavigationStack 绑定在一起。
@Bindable var router = Router() // 定义 router 变量
NavigationStack(path: $router.navPath) {
ContentView()
.navigationDestination(for: Router.Destination.self) { destination in
switch destination {
case .pageA(let models):
PageAView(models: models)
case .pageB:
PageBView()
}
}
}
.frame(width: CONTENT_VIEW_WIDTH, height: CONTENT_VIEW_HEIGHT)
.environment(router)
NavigationStack
的 path 传入的是 Router 的 path,这样 Router 就可以控制 NavigationStack
的页面跳转。在 navigationDestination
里处理各种页面的跳转。
.environment(router)
让 Router 传递给视图上的子视图,任意分支的子视图(包括子视图的子视图…)都可以拿到 Router 实例,控制页面跳转。
struct SubView: View {
@Environment(Router.self) var router: Router
private func gotoPageA() {
router.navigate(to: .pageA(models: models))
}
}