框架,为在 SwiftUI 中管理导航提供便捷的环境。
@State var isActive
这样的布尔标志@State var route: RouteAction?
这样带有大型 switch-case
语句的 enum
标志UIViewController
的隐式 UIKit
黑魔法框架只有两个 state object
,每个都隔离了 @State var isActive: Bool
和 @State var isPresent: Bool
标志的 "切换工作"。
像 UINavigationController
一样,它存储堆栈状态并使用 push
和 pop
方法提供堆栈转换
let navigationStackController = NavigationStackController()
// Standard usage
navigationStackController.push(Text("My View"))
navigationStackController.pop()
navigationStackController.popToRoot()
// Advanced usage
enum Screen: Hashable {
case detail
...
}
navigationStackController.push(tag: Screen.detail, DetailView())
navigationStackController.pop(to: Screen.detail)
它的伴侣是 NavigationStackView
– 对 NavigationView
的包装,将其与 NavigationStackController
绑定
struct ContentView: View {
@StateObject var navigationStackController = NavigationStackController()
var body: some View {
NavigationStackView(navigationStackController) {
RootView(
showDetails: { model in
navigationStackController.push(DetailView(model: model))
},
showSettings: {
navigationStackController.push(SettingsView())
}
)
}
}
}
// Another usage with automatic initialized NavigationStackController
struct ContentView: View {
var body: some View {
NavigationStackView { controller in
RootView(
showDetails: { model in
controller.push(DetailView(model: model))
},
showSettings: {
controller.push(SettingsView())
}
)
}
}
}
任何被 push 的视图都可以通过 EnvironmentObject
访问 NavigationStackView
的 NavigationStackController
struct DetailView: View {
let model: Model
@EnvironmentObject var navigationStackController: NavigationStackController
var body: some View {
VStack {
Text(model.title)
Button("pop to root") {
navigationStackController.popToRoot()
}
}
}
}
💫 额外特性: 您可以使用任何 Hashable
类型标记任何被 push 的视图。 它允许在 pop 时引用特定屏幕
navigationStackController.push(tag: "Screen 1", Screen1()))
navigationStackController.pop(to: "Screen 1")
像 NavigationStackController
一样,ModalStackController
控制模态堆栈层次结构并使用 present
和 dismiss
方法提供堆栈转换
let modalStackController = ModalStackController()
// Standard usage
modalStackController.present(.sheet, Text("My View"))
modalStackController.present(.fullScreenCover, Text("Another View"))
modalStackController.dismiss()
modalStackController.dismissAll()
// Advanced usage
enum Screen: Hashable {
case detail
...
}
modalStackController.present(.sheet, tag: Screen.detail, DetailView())
modalStackController.dismiss(to: Screen.detail)
🚧 注意: SwiftUI
不允许一次关闭多个视图! 因此,诸如 dismissAll()
或 dismiss(to:)
/dismiss(from:)
之类的方法将依次关闭所有视图。
它的伴侣是 ModalStackView
,它将 ModalStackController
与之绑定
struct ExampleApp: App {
@StateObject var modalStackController = ModalStackController()
var body: some Scene {
WindowGroup {
ModalStackView(modalStackController) {
RootView()
}
}
}
}
任何呈现的视图也可以通过 EnvironmentObject
访问 ModalStackController
struct RootView: View {
@EnvironmentObject var modalStackController: ModalStackController
var body: some View {
VStack {
Text("Home screen")
Button("FAQ") {
modalStackController.present(.sheet, FAQView())
}
Button("Authorize") {
modalStackController.present(.fullScreenCover, LoginView())
}
}
}
}
💫 就像在
NavigationStackController
中一样,您可以在使用ModalStackController
present 时标记呈现的视图
NavigationStackController
ModalStackController
PresentationStyle
可以,您可以。 该框架不影响以其他方式构建的导航,例如通过标准 @State var isActive: Bool
标志或通过 UIKit hack。
NavigationStackController
和 ModalStackController
创建本地状态并仅管理他们自己的状态。
不幸的是,该框架不支持使用 Alert
的这种机制,但是您可以通过类似于 ModalStackController
的方式自己实现它。
您的项目可以有许多不同的自定义呈现方式(popup
、snackbar
、toast
、notifications
),并且每种方式都需要特定的逻辑来处理层次结构,具体取决于它们的实现。
因此,不计划向框架添加新的呈现方法。
创建一个 Package.swift
文件。
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "YOUR_PROJECT_NAME",
dependencies: [
.package(url: "https://github.com/Ernest0-Production/ScreenNavigatorKit.git", from: "0.0.3")
],
targets: [
.target(name: "YOUR_TARGET_NAME", dependencies: ["ScreenNavigatorKit"])
]
)
ScreenNavigatorKit 在 MIT 许可证下发布。 有关详细信息,请参见LICENSE。