关于 swiftui-ui-patterns
swiftui-ui-patterns 为 SwiftUI 开发提供视图模式和组件参考,适用于构建新界面或改进现有项目。内容涵盖状态管理、导航、异步界面与预览,并强调组合式视图和明确的状态所有权。
主要功能
- 01SwiftUI 状态与数据流指导
- 02导航和弹窗接线参考
- 03异步状态处理建议
- 04组件模式与索引
- 05预览和性能参考
适用场景
- 01为现有项目添加 SwiftUI 屏幕
- 02搭建含标签页和导航的新应用
- 03实现异步加载及错误状态
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dimillian/ skills --skill swiftui-ui-patterns安装后在 Claude Code 中输入/swiftui-ui-patterns确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/app-wiring.mdasync-state.mdcomponents-index.mdcontrols.mddeeplinks.mdfocus.mdform.mdgrids.mdhaptics.mdinput-toolbar.mdlightweight-clients.mdlist.mdloading-placeholders.mdmacos-settings.mdmatched-transitions.mdmedia.mdmenu-bar.mdnavigationstack.mdoverlay.mdperformance.mdpreviews.mdscroll-reveal.mdscrollview.mdsearchable.mdsheets.mdsplit-views.mdtabview.mdtheming.mdtitle-menus.md详细介绍
SwiftUI UI 模式
快速开始
根据目标选择一条路线:
现有项目
- 确定功能或屏幕,以及主要交互模式(列表、详情、编辑器、设置、标签页)。
- 使用
rg "TabView\("或类似命令,在仓库中查找相近示例,然后阅读最接近的 SwiftUI 视图。 - 遵循项目本地约定:优先使用 SwiftUI 原生状态,尽可能让状态保持在本地,并通过环境注入共享依赖。
- 从
references/components-index.md中选择相关组件参考,并遵循其中的指导。 - 如果交互会在拖动或滚动移开主要内容时显示次要内容,请先阅读
references/scroll-reveal.md,再手动实现手势。 - 使用小巧、专注的子视图构建视图,并采用 SwiftUI 原生的数据流。
新项目脚手架
- 从
references/app-wiring.md开始,配置 TabView + NavigationStack + sheets。 - 根据提供的骨架添加最简的
AppTab和RouterPath。 - 根据首先需要的 UI,选择下一份组件参考(TabView、NavigationStack、Sheets)。
- 随着添加新屏幕,扩展路由和 sheet 枚举。
通用规则
- 使用现代 SwiftUI 状态(
@State、@Binding、@Observable、@Environment),避免不必要的视图模型。 - 如果部署目标包含 iOS 16 或更早版本,且无法使用 iOS 17 引入的 Observation API,则改用
ObservableObject:根视图持有时使用@StateObject,注入观察时使用@ObservedObject,仅在真正共享的应用级状态中使用@EnvironmentObject。 - 优先采用组合;保持视图小巧、专注。
- 使用 async/await 搭配
.task,并明确处理加载和错误状态。有关重启、取消和防抖的指导,请阅读references/async-state.md。 - 将共享应用服务放在
@Environment中,但对于功能本地的依赖和模型,优先通过显式初始化器注入。有关根视图配置模式,请阅读references/app-wiring.md。 - 优先使用适合部署目标的最新 SwiftUI API,并注明模式依赖的最低操作系统版本。
- 仅在编辑旧版文件时,才沿用现有的旧版模式。
- 遵循项目的格式化工具和样式指南。
- Sheets:当状态表示选定模型时,优先使用
.sheet(item:),而不是.sheet(isPresented:)。避免在 sheet 主体中使用if let。sheet 应自行管理操作,并在内部调用dismiss(),而不是转发onCancel/onConfirm闭包。 - 滚动驱动的显示效果:优先根据滚动偏移量推导归一化进度值,并以该单一事实来源驱动视觉状态。除非仅靠滚动无法表达该交互,否则避免并行的手势状态机。
状态所有权概要
使用与所有权模型相匹配、作用范围最小的状态工具:
| 场景 | 推荐模式 |
|---|---|
| 由单个视图拥有的本地 UI 状态 | @State |
| 子视图修改由父视图拥有的值状态 | @Binding |
| iOS 17+ 上由根视图拥有的引用模型 | 使用 @Observable 类型的 @State |
iOS 17+ 上子视图读取或修改注入的 @Observable 模型 | 将其作为存储属性显式传入 |
| 共享应用服务或配置 | @Environment(Type.self) |
| iOS 16 及更早版本上的旧版引用模型 | 根视图使用 @StateObject,注入时使用 @ObservedObject |
先确定所有权位置,再选择包装器。如果普通值状态已经足够,就不要引入引用模型。
跨领域参考资料
references/navigationstack.md:导航所有权、每个标签页的历史记录,以及基于枚举的路由。references/sheets.md:集中式模态呈现,以及由枚举驱动的工作表。references/deeplinks.md:URL 处理,以及将外部链接路由到应用目的地。references/app-wiring.md:根依赖图、环境的使用,以及应用外壳的连接方式。references/async-state.md:.task、.task(id:)、取消、防抖,以及异步 UI 状态。references/previews.md:#Preview、固定数据、模拟环境,以及隔离的预览设置。references/performance.md:稳定标识、观察范围、惰性容器,以及渲染成本防护措施。
反模式
- 在一个文件中混合布局、业务逻辑、网络请求、路由和格式化的大型视图。
- 使用多个布尔标志来控制互斥的工作表、警报或导航目的地。
- 在由
body驱动的代码路径中直接调用实时服务,而不是使用视图生命周期钩子或注入的模型/服务。 - 为解决本应通过更好的组合来解决的类型不匹配问题而使用
AnyView。 - 在没有明确所有权理由的情况下,默认将每个共享依赖都设为
@EnvironmentObject,或使用全局路由器。
新建 SwiftUI 视图的工作流
- 编写 UI 代码前,先确定视图的状态、所有权位置和最低 OS 要求。
- 确定哪些依赖应放在
@Environment中,哪些应作为显式初始化器输入保留。 - 勾勒视图层级、路由模型和呈现位置;将重复部分提取为子视图。对于复杂导航,请阅读
references/navigationstack.md、references/sheets.md或references/deeplinks.md。继续之前,先构建并确认没有编译器错误。 - 使用
.task或.task(id:)实现异步加载,并在需要时明确处理加载和错误状态。如果工作依赖不断变化的输入或取消,请阅读references/async-state.md。 - 为主要和次要状态添加预览,然后在 UI 可交互时添加辅助功能标签或标识符。如果视图需要固定数据或注入的模拟依赖,请阅读
references/previews.md。 - 通过构建进行验证:确认没有编译器错误,检查预览能否正常渲染且不会崩溃,确保状态变化能正确传递,并检查列表标识和观察范围是否会导致可避免的重复渲染。如果屏幕较大、滚动内容较多或更新频繁,请阅读
references/performance.md。对于常见的 SwiftUI 编译错误——缺少@State注解、ViewBuilder闭包不明确,或泛型类型不匹配——应先解决,再更新调用点。**如果构建失败:**仔细阅读错误消息,修复指出的问题,然后重新构建,再继续下一步。如果预览崩溃,请隔离出问题的子视图,确认其状态初始化有效,然后重新运行预览,再继续操作。
组件参考资料
请将 references/components-index.md 作为入口。每份组件参考资料都应包括:
- 意图和最适用的场景。
- 遵循本地约定的最简用法模式。
- 常见陷阱和性能说明。
- 当前仓库中现有示例的路径。
添加新的组件参考资料
- 创建
references/<component>.md。 - 内容应简短且便于执行;链接到当前仓库中的具体文件。
- 在
references/components-index.md中添加新条目。
评论
支持 Markdown