最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
TCACoordinators:实践指南
时间:2026-09-10 20:34:01 编辑:袖梨 来源:一聚教程网
面对实际交付,我看TCACoordinators的重点不在星标,而在这项能力:通过协调器模式在可组合架构中进行强大的导航。在日常自动化场景里,常见问题是输入边界、依赖和失败处理如果不清楚就很难稳定复用,这正是评估时需要盯住的地方。试跑可以从用一项范围明确的真实任务完成最小试跑开始,并把配置时间、输出质量、异常信息和维护痕迹写进验收记录。它更像给愿意先做小范围验证并复查原始文档的团队准备的可审查方案,是否长期使用应由试跑数据决定。
TCACoordinators
可组合架构中的协调器模式
TCACoordinators 使用 可组合架构 (TCA) 在 SwiftUI 中带来灵活的导航方法。它允许您使用提升到高级协调器中的单个状态来管理复杂的导航和表示流。使用此模式,您可以编写独立的屏幕功能,这些功能对其在应用程序的导航流程中的上下文的了解为零。它通过将 TCA 中的现有工具与 中的现有工具相结合来实现这一目标,这是一种在 SwiftUI 中处理导航的新颖方法。
如果您愿意,您可能会喜欢这个库:
✅ 支持深层链接到 app. 中的_深层_嵌套导航路线 ✅ 在不同的导航中轻松重复使用屏幕功能 contexts.
✅ 轻松返回根屏幕或导航中的特定屏幕 stack.
✅ 将所有导航逻辑保存在一个 place. 中 ✅ 将应用程序的导航分解为多个可重用的协调器并将它们组合起来 together.
✅ 使用单一系统统一推送导航和模态 presentation.
该库的工作原理是将屏幕数组转换为 NavigationStacks 和演示调用的层次结构,因此:
它不依赖于 all. 的 UIKit 它不会尝试从 scratch. 重新创建 SwiftUI 导航
使用示例
第 1 步 - 创建屏幕缩小器
首先,确定属于您正在建模的特定导航流程一部分的所有可能的屏幕。目标是将他们的减速器组合成一个减速器 - 一个可以驱动任何这些屏幕的行为的减速器。得益于 @Reducer macro,这可以通过枚举减速器 e.g 轻松实现。以下(其中 Home、NumbersList 和 NumberDetail 是单独的屏幕缩小器):
@Reducer(state: .hashable)
enum Screen {
case home(Home)
case numbersList(NumbersList)
case numberDetail(NumberDetail)
}
第 2 步 - 创建协调器减速器
协调器将管理导航流程中的多个屏幕。它的状态应该包括一个Route<Screen.State>s的数组,代表导航堆栈:i.e。向该数组添加新的屏幕状态将触发相应的屏幕被推送或呈现。 Route 是一个枚举,其情况捕获屏幕状态及其显示方式,e.g。 case push(Screen.State)。
@Reducer
struct Coordinator {
@ObservableState
struct State: Equatable {
var routes: [Route<Screen.State>]
}
...
}
协调器的操作应该包括一个特殊情况,它允许将屏幕操作分派到路由数组中的正确屏幕,并允许自动更新路由数组,e.g。当用户点击“返回”时:
@Reducer
struct Coordinator {
...
enum Action {
case router(IndexedRouterActionOf<Screen>)
}
...
}
协调器减速器定义用于呈现和消除屏幕的任何逻辑,并使用 forEachRoute 进一步将 Screen 减速器应用到 routes 数组中的每个屏幕。 forEachRoute 采用两个参数:路由数组的键路径和路由器操作案例的案例路径:
@Reducer
struct Coordinator {
...
var body: some ReducerOf<Self> {
Reduce<State, Action> { state, action in
switch action {
case .router(.routeAction(_, .home(.startTapped))):
state.routes.presentSheet(.numbersList(.init(numbers: Array(0 ..< 4))), embedInNavigationView: true)
case .router(.routeAction(_, .numbersList(.numberSelected(let number)))):
state.routes.push(.numberDetail(.init(number: number)))
case .router(.routeAction(_, .numberDetail(.showDouble(let number)))):
state.routes.presentSheet(.numberDetail(.init(number: number * 2)))
case .router(.routeAction(_, .numberDetail(.goBackTapped))):
state.routes.goBack()
default:
break
}
return .none
}
.forEachRoute(.routes, action: .router)
}
}
第 3 步 - 创建协调器视图
完成后,就可以创建 CoordinatorView。它将使用 TCARouter,它将路由数组转换为具有不可见 NavigationLinks 和演示调用的屏幕视图的嵌套列表,所有这些都配置了对路由数组的更改做出适当反应的绑定。除了作用域存储之外,TCARouter 还采用一个闭包,可以为导航流中的任何屏幕创建视图。 switch 语句是实现这一目标的自然方法,每个可能的屏幕都有一个案例:
struct CoordinatorView: View {
let store: StoreOf<Coordinator>
var body: some View {
TCARouter(store.scope(state: .routes, action: .router)) { screen in
switch screen.case {
case let .home(store):
HomeView(store: store)
case let .numbersList(store):
NumbersListView(store: store)
case let .numberDetail(store):
NumberDetailView(store: store)
}
}
}
}
便捷方法
可以使用普通的数组方法(例如 append)来管理路由数组,但也有许多方便的方法可用于常见的转换,例如:
| 方法 | 效果 |
|---|---|
| 推 | 将新屏幕推入堆栈。 |
| presentSheet | 将新屏幕显示为工作表。† |
| presentCover | 将新屏幕呈现为全屏封面。† |
| goBack | 返回堆栈中的一个屏幕。 |
| goBackToRoot | 返回到堆栈中的第一个屏幕。 |
| goBackTo | 返回到堆栈中的特定屏幕。 |
| 流行音乐 | 如果当前屏幕被按下,则弹出当前屏幕。 |
| 解雇 | 关闭最近呈现的屏幕。 |
† 如果您希望能够从呈现的屏幕推送屏幕,请通过 embedInNavigationView: true。
路线数组自动更新
如果用户点击后退按钮,路线数组将自动更新以反映新的导航状态。使用边缘滑动手势或通过长按后退按钮上的手势向后导航也将自动更新路线数组,滑动以关闭工作表也会自动更新。
取消解雇时的飞行效果
默认情况下,当弹出或关闭特定屏幕时,由特定屏幕启动的任何飞行中效果都会自动取消。要选择退出自动取消,请将 cancellationId: nil 传递给 forEachRoute。
深度链接
SwiftUI 不支持在单个状态更新中呈现多个屏幕。在NavigationStack APIs推出之前,在一次状态更新中推送多个屏幕也是如此。这使得在导航层次结构中深层链接到屏幕的多个层变得困难。使用 TCACoordinators,您可以进行任何此类更改,并且库将在幕后将较大的更新分解为 SwiftUI 支持的一系列较小的更新,并在必要时在中间添加延迟。
作曲儿童协调员
协调器就像可组合架构中的任何其他 UI 单元一样 - 包括 View 和 Reducer,以及 State 和 Action 类型。这意味着它们可以按照 SwiftUI 和 TCA 允许的正常方式进行组合。但是,在将应用程序的屏幕流分解为相关屏幕的多个不同流时,需要记住一些限制:请参阅 嵌套协调器。
识别屏幕
在给出的示例中,Coordinator.Action 的路由器案例包括 IndexedRouterActionOf<Screen> 的关联值。这意味着屏幕是通过其在路由数组中的索引来标识的。这是安全的,因为索引对于标准导航更新 - e.g 来说是稳定的。推送和弹出不会影响现有屏幕的索引。但是,如果您更喜欢使用 Identifiable 屏幕,则可以将屏幕作为 IdentifiedArray 进行管理。 Coordinator.Action 的路由器案例将具有 IdentifiedRouterActionOf<Screen> 的关联值,并受益于与上面示例相同的简洁 API。
灵活且可重复使用
如果需要更改屏幕流程,可以在一处轻松进行更改。屏幕视图和缩减器(以及它们的状态和操作类型)不再需要了解导航流中的任何其他屏幕 - 它们可以简单地发送操作并让协调器决定是否应推送或呈现新视图 - 这使得在不同上下文中重用它们变得容易,并有助于将屏幕职责与导航职责分开。
它是如何运作的?
该库使用 FlowStacks 将导航状态提升到各个屏幕之外。 FlowStacks 也可以用于不使用可组合架构的 SwiftUI 项目。
从早期版本迁移
从 v0.8 及更低
API 从 v0.8 更改为 v0.9,以使库的 APIs 更加符合可组合架构,包括案例路径的使用。如果您要迁移到这些新的 APIs,请参阅 迁移文档。
从 v0.11 及更低
v0.12 引入了屏幕缩小器的状态符合 Hashable 的要求:请参阅 迁移文档。
相关文章
- rgbdslam_v2:实践指南 09-10
- tplink路由器帐号登不进去怎么办(tplink路由器帐号登不进去有什么办法解决) 09-10
- tplink300m无线扩展器如何设置(tplink300m无线扩展器设置方法) 09-10
- 灵兽大冒险麒麟怎么处理-任务条件 09-10
- 灵兽大冒险法宝怎么处理-任务条件 09-10
- 灵兽大冒险天慧星麒麟通关有哪些重点-关键信息和实际影响 09-10