🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx @anthropic-ai/skills install avdlee/swiftui-agent-skill/swiftui-expert-skill
💡 提示:需要 Node.js 和 NPM
SwiftUI 专家技能
概述
使用此技能来构建、审查或改进 SwiftUI 功能,确保正确的状态管理、最佳的视图组合以及 iOS 26+ 的 Liquid Glass 样式。优先考虑原生应用程序编程接口、苹果设计指南和注重性能的模式。本技能侧重于事实和最佳实践,不强制特定的架构模式。
工作流决策树
1) 审查现有 SwiftUI 代码
- 首先,查阅
references/latest-apis.md以确保仅使用当前、非弃用的应用程序编程接口 - 对照选择指南检查属性包装器的使用情况(参见
references/state-management.md) - 验证视图组合是否符合提取规则(参见
references/view-structure.md) - 检查是否应用了性能模式(参见
references/performance-patterns.md) - 验证列表模式是否使用了稳定的标识(参见
references/list-patterns.md) - 检查动画模式是否正确(参见
references/animation-basics.md,references/animation-transitions.md) - 审查可访问性:正确的分组、特性、动态类型支持(参见
references/accessibility-patterns.md) - 检查图表模式是否正确使用标记、稳定数据标识以及可用性门控(参见
references/charts.md;可访问性和回退策略参见references/charts-accessibility.md) - 对于 macOS 目标:验证是否正确使用了特定于 macOS 的应用程序编程接口和模式(参见
references/macos-scenes.md,references/macos-window-styling.md,references/macos-views.md) - 检查 Liquid Glass 的使用是否正确且一致(参见
references/liquid-glass.md) - 验证 iOS 26+ 可用性处理,并提供合理的回退
2) 改进现有 SwiftUI 代码
- 首先,查阅
references/latest-apis.md以将所有弃用的应用程序编程接口替换为现代等效项 - 审计状态管理,确保选择了正确的包装器(参见
references/state-management.md) - 将复杂的视图提取到单独的子视图中(参见
references/view-structure.md) - 重构热路径以最小化冗余状态更新(参见
references/performance-patterns.md) - 确保 ForEach 使用稳定的标识(参见
references/list-patterns.md) - 改进动画模式(使用 value 参数、正确的过渡,参见
references/animation-basics.md,references/animation-transitions.md) - 改进可访问性:使用
Button而不是点击手势,为动态类型添加@ScaledMetric(参见references/accessibility-patterns.md) - 审查图表代码,确保修饰符作用域、样式和可访问性正确(参见
references/charts.md,references/charts-accessibility.md) - 对于 macOS 目标:在适当的地方采用特定于 macOS 的应用程序编程接口(MenuBarExtra、Settings、Table、Commands 等)(参见
references/macos-scenes.md,references/macos-window-styling.md,references/macos-views.md) - 当使用
UIImage(data:)时,建议进行图像下采样(作为可选优化,参见references/image-optimization.md) - 仅在用户明确要求时采用 Liquid Glass
3) 实现新的 SwiftUI 功能
- 首先,查阅
references/latest-apis.md以针对目标部署版本仅使用当前、非弃用的应用程序编程接口 - 首先设计数据流:识别拥有的状态 vs 注入的状态(参见
references/state-management.md) - 为最佳差异对比构建视图(尽早提取子视图,参见
references/view-structure.md) - 将业务逻辑保留在服务和模型中,以便于测试(参见
references/layout-best-practices.md) - 使用正确的动画模式(隐式 vs 显式、过渡,参见
references/animation-basics.md,references/animation-transitions.md,references/animation-advanced.md) - 对可点击元素使用
Button,添加可访问性分组和标签(参见references/accessibility-patterns.md) - 对于图表:使用正确的标记类型、稳定的数据标识,并对 iOS 17+/18+/26+ 应用程序编程接口进行门控(参见
references/charts.md;可访问性参见references/charts-accessibility.md) - 对于 macOS 目标:使用特定于 macOS 的场景(参见
references/macos-scenes.md)、窗口样式(参见references/macos-window-styling.md)以及 HSplitView、Table 等视图(参见references/macos-views.md) - 在布局/外观修饰符之后应用玻璃效果(参见
references/liquid-glass.md) - 使用
#available对 iOS 26+ 功能进行门控,并提供回退
核心指南
状态管理
@State必须是private;用于内部视图状态@Binding仅当子视图需要修改父视图状态时使用- 当视图创建对象时使用
@StateObject;当注入时使用@ObservedObject - iOS 17+:将
@State与@Observable类一起使用;对于需要绑定的注入的可观察对象,使用@Bindable - 对只读值使用
let;对需要响应式读取的值使用var+.onChange() - 切勿将值传递给
@State或@StateObject——它们仅接受初始值 - 嵌套的
ObservableObject不会传播更改——将嵌套对象直接传递给子视图;@Observable可以很好地处理嵌套
视图组合
- 将复杂视图提取到单独的子视图中,以提高可读性和性能
- 对于状态更改,优先使用修饰符而不是条件视图(保持视图标识)
- 保持视图的
body简单且纯粹(无副作用或复杂逻辑) - 仅对小的、简单的部分使用
@ViewBuilder函数 - 优先使用
@ViewBuilder let content: Content而不是基于闭包的内容属性 - 将业务逻辑保留在服务和模型中;视图应协调用户界面流程
- 操作处理程序应引用方法,而不是包含内联逻辑
- 视图应在任何上下文中工作(不要假设屏幕大小或呈现样式)
性能
- 仅将需要的值传递给视图(避免大型”配置”或”上下文”对象)
- 消除不必要的依赖以减少更新扇出
- 考虑在列表中使用每个项的
@Observable状态对象,以缩小更新/依赖范围 - 考虑频繁变化的值是否适合放在环境中;优先使用更局部的状态,以减少不必要的视图更新
- 在热路径中分配状态之前,检查值是否已更改
- 避免在
onReceive、onChange、滚动处理程序中产生冗余的状态更新 - 最小化频繁执行的代码路径中的工作量
- 对大型列表使用
LazyVStack/LazyHStack - 为
ForEach使用稳定的标识(切勿对动态内容使用.indices) - 确保每个
ForEach元素的视图数量恒定 - 避免在
ForEach中进行内联过滤(预先过滤并缓存) - 避免在列表行中使用
AnyView - 考虑对快速差异对比使用纯数据视图(或将昂贵的视图包装在纯数据父视图中)
- 当遇到
UIImage(data:)时,建议进行图像下采样(作为可选优化) - 避免布局抖动(深层层次结构、过多的
GeometryReader) - 通过阈值门控频繁的几何更新
- 使用
Self._logChanges()或Self._printChanges()调试意外的视图更新 Shape.path()、visualEffect、Layout和onGeometryChange闭包可能不在主线程上运行——应捕获值,而不是访问@MainActor状态
动画
- 使用带有 value 参数的
.animation(_:value:)(已弃用的无 value 版本过于宽泛) - 对事件驱动的动画(按钮点击、手势)使用
withAnimation - 为提高性能,优先使用变换(
offset、scale、rotation)而不是布局更改(frame) - 过渡需要条件结构外部的动画
- 自定义
Animatable实现必须具有显式的animatableData(或在 iOS 26+ 上使用@Animatable宏) - iOS 26+:使用
@Animatable宏自动合成animatableData;使用@AnimatableIgnored排除属性 - 对多步骤序列使用
.phaseAnimator(iOS 17+) - 对精确时序控制使用
.keyframeAnimator(iOS 17+) - 动画完成处理程序需要
.transaction(value:)才能重新执行 - 隐式动画覆盖显式动画(视图树中后出现的获胜)
可访问性
- 对于可点击元素,优先使用
Button而不是onTapGesture(免费的旁白支持) - 对应随动态类型缩放的数值使用
@ScaledMetric - 使用
accessibilityElement(children: .combine)将相关元素分组,形成组合标签 - 当默认标签不清晰或缺失时,提供
accessibilityLabel - 对于应表现得像原生控件的自定义控件,使用
accessibilityRepresentation
Liquid Glass (iOS 26+)
仅在用户明确要求时采用。
- 使用原生
glassEffect、GlassEffectContainer和玻璃按钮样式 - 将多个玻璃元素包裹在
GlassEffectContainer中 - 在布局和视觉修饰符之后应用
.glassEffect() - 仅对可交互/可聚焦元素使用
.interactive() - 将
glassEffectID与@Namespace一起用于变形过渡
快速参考
属性包装器选择
| 包装器 | 何时使用 |
|---|---|
@State |
内部视图状态(必须是 private) |
@Binding |
子视图修改父视图状态 |
@StateObject |
视图拥有一个 ObservableObject |
@ObservedObject |
视图接收一个 ObservableObject |
@Bindable |
iOS 17+:注入的 @Observable 需要绑定 |
let |
来自父视图的只读值 |
var |
通过 .onChange() 观察的只读值 |
Liquid Glass 模式
// 基础玻璃效果,带回退
if #available(iOS 26, *) {
content
.padding()
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
content
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
// 分组的玻璃元素
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
GlassButton1()
GlassButton2()
}
}
// 玻璃按钮
Button("确认") { }
.buttonStyle(.glassProminent)
审查清单
最新应用程序编程接口(参见 references/latest-apis.md)
- 未使用已弃用的修饰符(对照快速查找表检查)
- 应用程序编程接口选择与项目的最低部署目标匹配
状态管理
-
@State属性是private -
@Binding仅用于子视图修改父视图状态 - 拥有的状态使用
@StateObject,注入的状态使用@ObservedObject - iOS 17+:
@State与@Observable一起使用,注入的状态使用@Bindable - 传递的值未声明为
@State或@StateObject - 避免嵌套
ObservableObject(或直接传递给子视图)
表单与导航(参见 references/sheet-navigation-patterns.md)
- 对基于模型的表单使用
.sheet(item:) - 表单拥有其操作并在内部关闭
滚动视图(参见 references/scroll-patterns.md)
- 使用
ScrollViewReader和稳定标识进行程序化滚动
视图结构(参见 references/view-structure.md)
- 使用修饰符而不是条件语句来处理状态更改
- 复杂视图已提取到单独的子视图中
- 容器视图使用
@ViewBuilder let content: Content - 在分层视图上,在
.clipShape()之前使用.compositingGroup()
性能(参见 references/performance-patterns.md)
- 视图
body保持简单且纯粹(无副作用) - 仅传递所需的值(而不是大型配置对象)
- 消除了不必要的依赖
- 考虑在有助于性能时,使 @Observable 依赖尽可能细粒度(例如,列表行的每项数据)
- 状态更新在分配前检查值是否已更改
- 热路径最小化状态更新
-
body中未创建对象 - 繁重计算已移出
body - Sendable 闭包捕获值,而不是访问 @MainActor 状态
列表模式(参见 references/list-patterns.md)
- ForEach 使用稳定的标识(不是
.indices) - 每个 ForEach 元素的视图数量恒定
- ForEach 中没有内联过滤
- 列表行中没有
AnyView
布局(参见 references/layout-best-practices.md)
- 避免布局抖动(深层层次结构、过多的 GeometryReader)
- 通过阈值门控频繁的几何更新
- 业务逻辑保留在服务和模型中(不在视图中)
- 操作处理程序引用方法(不是内联逻辑)
- 使用相对布局(不是硬编码常量)
- 视图在任何上下文中工作(上下文无关)
动画(参见 references/animation-basics.md, references/animation-transitions.md, references/animation-advanced.md)
- 使用带有 value 参数的
.animation(_:value:) - 对事件驱动的动画使用
withAnimation - 过渡与条件结构外部的动画配对
- 自定义
Animatable具有显式的animatableData(或在 iOS 26+ 上使用@Animatable宏) - 为提高动画性能,优先使用变换而不是布局更改
- 对多步骤序列使用阶段动画(iOS 17+)
- 对精确时序使用关键帧动画(iOS 17+)
- 完成处理程序使用
.transaction(value:)进行重新执行
可访问性(参见 references/accessibility-patterns.md)
- 对可点击元素使用
Button而不是onTapGesture - 对应随动态类型缩放的数值使用
@ScaledMetric - 使用
accessibilityElement(children:)对相关元素进行分组 - 适当时对自定义控件使用
accessibilityRepresentation
图表(参见 references/charts.md, references/charts-accessibility.md)
- 在使用图表类型的文件中包含
import Charts - 图表数据模型使用
Identifiable(或显式的id:键路径) - 应用于整个图表的修饰符应添加到
Chart,而不是单个标记 - iOS 17+ 应用程序编程接口(
SectorMark、选择、可滚动轴)已进行可用性门控 - iOS 18+ 应用程序编程接口(如
LinePlot、AreaPlot)已进行可用性门控 - iOS 26+ 应用程序编程接口(
Chart3D、SurfacePlot)已进行可用性门控 - 为轴和可访问性使用了有意义的
.value()标签 - 对分类系列使用
foregroundStyle(by:)(而不是手动为每个标记设置颜色)
macOS 应用程序编程接口(参见 references/macos-scenes.md, references/macos-window-styling.md, references/macos-views.md)
- 对偏好设置使用
Settings场景(而不是自定义窗口) - 对菜单栏项使用
MenuBarExtra(而不是 AppKit 的NSStatusItem) - 对菜单栏菜单使用
Commands/CommandGroup/CommandMenu -
Table在 iOS 紧凑尺寸类下会进行调整(第一列显示组合信息) - 使用
defaultSize、windowResizability和frame(minWidth:minHeight:)配置窗口大小 - macOS 专用代码包裹在
#if os(macOS)条件中 - 使用具有正确
makeNSView/updateNSView生命周期的NSViewRepresentable - 对基于侧边栏的导航使用
NavigationSplitView(而不是HSplitView) -
HSplitView/VSplitView保留用于集成开发环境风格的等分窗格
Liquid Glass (iOS 26+)
- 对 Liquid Glass 使用
#available(iOS 26, *)并带有回退 - 多个玻璃视图包裹在
GlassEffectContainer中 -
.glassEffect()在布局/外观修饰符之后应用 -
.interactive()仅用于用户可交互元素 - 相关元素的形状和色调保持一致
参考资料
references/latest-apis.md– 所有工作流的必读文件。 按版本划分的从弃用到现代应用程序编程接口的过渡指南(iOS 15+ 到 iOS 26+)references/state-management.md– 属性包装器和数据流references/view-structure.md– 视图组合、提取和容器模式references/performance-patterns.md– 性能优化技术和反模式references/list-patterns.md– ForEach 标识、稳定性、Table(iOS 16+)和列表最佳实践references/layout-best-practices.md– 布局模式、上下文无关视图和可测试性references/accessibility-patterns.md– 可访问性特性、分组、动态类型和旁白references/animation-basics.md– 核心动画概念、隐式/显式动画、时序、性能references/animation-transitions.md– 过渡、自定义过渡、Animatable 协议references/animation-advanced.md– 事务、阶段/关键帧动画(iOS 17+)、完成处理程序(iOS 17+)、@Animatable宏(iOS 26+)references/charts.md– Swift Charts 标记、轴、选择、样式、组合和 Chart3D(iOS 26+)references/charts-accessibility.md– 图表可访问性(旁白、音频图、AXChartDescriptorRepresentable)、回退策略和全球开发者大会讲座references/sheet-navigation-patterns.md– 表单呈现、NavigationSplitView、检查器和导航模式references/scroll-patterns.md– ScrollView 模式和程序化滚动references/image-optimization.md– AsyncImage、图像下采样和优化references/liquid-glass.md– iOS 26+ Liquid Glass 应用程序编程接口references/macos-scenes.md– macOS 场景类型:Settings、MenuBarExtra、WindowGroup、Window、UtilityWindow、DocumentGroupreferences/macos-window-styling.md– macOS 窗口配置:工具栏样式、大小、位置、NavigationSplitView、检查器、Commandsreferences/macos-views.md– macOS 视图和组件:HSplitView、VSplitView、Table、PasteButton、文件对话框、拖放、AppKit 互操作
理念
本技能侧重于事实和最佳实践,而非架构观点:
- 我们不强制执行特定的架构(例如,MVVM、VIPER)
- 我们确实鼓励为了可测试性而分离业务逻辑
- 我们针对性能和可维护性进行优化
- 我们遵循苹果的人机界面指南和应用程序编程接口设计模式
📄 原始文档
完整文档(英文):
https://skills.sh/avdlee/swiftui-agent-skill/swiftui-expert-skill
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)