SwiftUI UI Patterns 提供以示例驱动的方式,指导 SwiftUI 视图与组件的构建,适用于创建或重构 SwiftUI UI、设计标签页架构等场景。
一、快速上手 根据目标选择路径。
已有项目:
- 确定功能或屏幕,以及主要交互模型(列表、详情、编辑器、设置、标签页)。
- 在仓库中查找就近示例,例如使用 rg "TabView(" 等命令,然后阅读最接近的 SwiftUI 视图。
- 应用本地约定:优先使用 SwiftUI 原生状态,尽量将状态保持为局部,对共享依赖使用环境注入。
- 从 references/components-index.md 中选择相关组件参考并遵循其指导。
- 使用小而专注的子视图和 SwiftUI 原生数据流来构建视图。
新项目脚手架:
- 从 references/app-scaffolding-wiring.md 开始,接线 TabView + NavigationStack + sheets。
- 基于提供的骨架添加最小化的 AppTab 与 RouterPath。
- 根据你首先需要的 UI 选择下一个组件参考(TabView、NavigationStack、Sheets)。
- 随着新屏幕的添加,扩展 route 与 sheet 的枚举。
二、通用规则
- 使用现代 SwiftUI 状态(@State、@Binding、@Observable、@Environment),避免不必要的视图模型。
- 偏好组合;保持视图小而专注。
- 使用 async/await 配合 .task 以及显式的加载/错误状态。
- 仅在编辑遗留文件时保留既有遗留模式。
- 遵循项目的格式化器与风格指南。
- Sheets:当状态表示选中的模型时,优先使用 .sheet(item:) 而非 .sheet(isPresented:)。避免在 sheet body 内使用 if let。Sheet 应拥有自己的动作并在内部调用 dismiss(),而不是转发 onCancel/onConfirm 闭包。
三、新建 SwiftUI 视图的工作流
- 定义视图的状态及其所有权位置。
- 确定要通过 @Environment 注入的依赖。
- 勾勒视图层级,将重复部分抽取为子视图。
- 用 .task 实现异步加载,必要时使用显式状态枚举。
- 当 UI 可交互时,添加无障碍标签或标识符。
- 通过构建进行验证,并在需要时更新使用处的调用点。
四、组件参考 使用 references/components-index.md 作为入口点。每个组件参考应包含:
- 意图与最适用的场景。
- 符合本地约定的最小使用模式。
- 陷阱与性能说明。
- 当前仓库中已有示例的路径。
五、Sheet 模式 item 驱动的 sheet(推荐):
@State private var selectedItem: Item?
.sheet(item: $selectedItem) { item in EditItemSheet(item: item) }
Sheet 拥有自己的动作:
struct EditItemSheet: View { @Environment(.dismiss) private var dismiss @Environment(Store.self) private var store
let item: Item
@State private var isSaving = false
var body: some View {
VStack {
Button(isSaving ? "Saving…" : "Save") {
Task { await save() }
}
}
}
private func save() async {
isSaving = true
await store.save(item)
dismiss()
}
}
六、新增组件参考
- 创建 references/<component>.md。
- 保持简短且可操作;链接到当前仓库中的具体文件。
- 用新条目更新 references/components-index.md。