🚀 快速安装

复制以下命令并运行,立即安装此 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 状态对象,以缩小更新/依赖范围
  • 考虑频繁变化的值是否适合放在环境中;优先使用更局部的状态,以减少不必要的视图更新
  • 在热路径中分配状态之前,检查值是否已更改
  • 避免在 onReceiveonChange、滚动处理程序中产生冗余的状态更新
  • 最小化频繁执行的代码路径中的工作量
  • 对大型列表使用 LazyVStack/LazyHStack
  • ForEach 使用稳定的标识(切勿对动态内容使用 .indices
  • 确保每个 ForEach 元素的视图数量恒定
  • 避免在 ForEach 中进行内联过滤(预先过滤并缓存)
  • 避免在列表行中使用 AnyView
  • 考虑对快速差异对比使用纯数据视图(或将昂贵的视图包装在纯数据父视图中)
  • 当遇到 UIImage(data:) 时,建议进行图像下采样(作为可选优化)
  • 避免布局抖动(深层层次结构、过多的 GeometryReader
  • 通过阈值门控频繁的几何更新
  • 使用 Self._logChanges()Self._printChanges() 调试意外的视图更新
  • Shape.path()visualEffectLayoutonGeometryChange 闭包可能不在主线程上运行——应捕获值,而不是访问 @MainActor 状态

动画

  • 使用带有 value 参数的 .animation(_:value:)(已弃用的无 value 版本过于宽泛)
  • 对事件驱动的动画(按钮点击、手势)使用 withAnimation
  • 为提高性能,优先使用变换(offsetscalerotation)而不是布局更改(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+)

仅在用户明确要求时采用。

  • 使用原生 glassEffectGlassEffectContainer 和玻璃按钮样式
  • 将多个玻璃元素包裹在 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+ 应用程序编程接口(如 LinePlotAreaPlot)已进行可用性门控
  • iOS 26+ 应用程序编程接口(Chart3DSurfacePlot)已进行可用性门控
  • 为轴和可访问性使用了有意义的 .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 紧凑尺寸类下会进行调整(第一列显示组合信息)
  • 使用 defaultSizewindowResizabilityframe(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、DocumentGroup
  • references/macos-window-styling.md – macOS 窗口配置:工具栏样式、大小、位置、NavigationSplitView、检查器、Commands
  • references/macos-views.md – macOS 视图和组件:HSplitView、VSplitView、Table、PasteButton、文件对话框、拖放、AppKit 互操作

理念

本技能侧重于事实和最佳实践,而非架构观点:

  • 我们不强制执行特定的架构(例如,MVVM、VIPER)
  • 我们确实鼓励为了可测试性而分离业务逻辑
  • 我们针对性能和可维护性进行优化
  • 我们遵循苹果的人机界面指南和应用程序编程接口设计模式

📄 原始文档

完整文档(英文):

https://skills.sh/avdlee/swiftui-agent-skill/swiftui-expert-skill

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。