为使用 ComposableArchitecture 构建的 SwiftUI 应用程序提供呈现和导航辅助工具。
如果您熟悉 ComposableArchitecture,您就应该知道如何从隔离的组件构建一个功能齐全的应用程序。您可以通过组合 reducer 和作用域 store 来实现。但是,当一个组件可选地嵌入另一个组件(或者意味着在导航中呈现)时,正确处理副作用可能会变得棘手。
ComposablePresentation
是一个库,它有助于在用 ComposableArchitecture 构建的应用程序中组合 reducer。 每当您需要有条件地呈现一个组件时,都可以使用它,例如呈现 sheet、在屏幕之间导航或显示组件列表。它还附带了 SwiftUI 辅助工具,用于 sheet、导航链接、for-each-store 和其他呈现方式。
.presenting
高阶 reducer 允许将 reducer 与可选呈现组件的 reducer 组合。一旦组件被解除 (其可选状态从有效值变为 nil
),其 reducer 返回的 effect 将自动取消。
有关该概念的更多信息,请参见文章:SwiftUI 导航的思考。
ComposablePresentation (Xcode Workspace)
├─ swift-composable-presentation (Swift Package)
| └─ ComposablePresentation (Library)
└─ Example (Xcode Project)
└─ Example (iOS Application)
使用 Swift Package Manager 将 ComposablePresentation
添加为项目的依赖项。
此存储库包含一个使用 SwiftUI 和 ComposableArchitecture 构建的 iOS 应用程序示例。
ComposablePresentation.xcworkspace
。Example
Xcode 项目中。Example
构建方案运行该应用程序。SwiftUI 示例,展示了如何使用具有可选状态的 store 驱动的内容呈现 sheet。 当 store 的状态具有有效值时,该 sheet 会呈现,并在变为 nil
时解除。 当 sheet 被解除时,store 的 reducer 在内容呈现期间产生的所有 effect 都会被取消。
SwiftUI 示例,展示了如何使用具有可选状态的 store 驱动的内容呈现全屏覆盖。 当 store 的状态具有有效值时,该覆盖会呈现,并在变为 nil
时解除。 当覆盖被解除时,store 的 reducer 在内容呈现期间产生的所有 effect 都会被取消。
使用 .navigationDestination
的 SwiftUI 示例,由具有可选状态的 store 驱动。 当 store 的状态具有有效值时,链接处于活动状态,并在变为 nil
时变为非活动状态。 当目标被解除时,store 的 reducer 在内容呈现期间产生的所有 effect 都会被取消。
具有组件列表的 SwiftUI 示例。 从列表中删除组件时,其 reducer 产生的所有 effect 都会被取消。
SwiftUI 示例,展示了如何在状态驱动的导航中一次性解除多个导航链接(弹回根视图)。 呈现的 store 的 reducer 产生的所有 effect 都会在解除时被取消。
在大多数情况下,呈现具有相应的呈现和解除动画。 当我们使用可选状态驱动它时,就会出现问题。 假设我们要以编程方式解除 sheet,因此我们将其状态设置为 nil
。 它会触发解除动画,但由于我们的状态已经是 nil
,因此我们无法在此过渡期间呈现 sheet 内容。 作为一种解决方法,ComposablePresentation
提供了 replayNonNil
函数,该函数可以传递给 NavigationLinkWithStore
、View.sheet
、View. popover
和其他 SwiftUI 辅助函数的可选 mapState
参数。
一个组件的 SwiftUI 示例,该组件有条件地呈现两个子组件之一。 该状态建模为一个具有两种情况的枚举。 当子组件从父组件中删除时,子组件产生的所有 effect 都会被取消。
一个组件的 SwiftUI 示例,该组件呈现一个互斥的目标。 目标由一个可选的枚举 case 表示。 每个 case 都使用不同的导航模式(导航链接、sheet、alert 等)呈现。 当目标被解除或更改时,呈现的组件产生的所有 effect 都会被取消。 这种导航建模设计灵感来自 Point-Free 的“Modern SwiftUI”视频系列。
使用此库组合的导航由声明性状态驱动。 这使得处理 deep link 并导航到应用程序的任何屏幕变得容易。 应用了一些解决方法来修复 SwiftUI 导航问题(这仅仅是因为 swiftui-navigation 库 by Point-Free)。 更改 Example/App.swift 中的初始状态,以便在应用程序启动时导航到任何屏幕。
使用 Store
驱动 NavigationStack
的 SwiftUI 示例。 该状态提供了一个可识别的目标状态数组,其索引构成导航路径。 当数组发生变异时,就会发生导航。 此示例需要 iOS ≥ 16。
ComposablePresentation.xcworkspace
ComposablePresentation
scheme 来构建库和运行单元测试。Copyright © 2021 Dariusz Rybicki Darrarski
许可证:MIT