SuperAPI AI 工具集

swiftui-view-refactor

前端与建站

查看项目

更新于 10-15 11:23

技能介绍

用途

SwiftUI View Refactor 用于将 SwiftUI 视图文件重构为稳定、可测试的结构。适用场景包括:拆分过大的视图、收紧数据流、清理 Observation 所有权。其核心方向是把视图变成小而明确、稳定的视图类型。

主要能力

该技能围绕一组核心准则展开。

视图声明顺序(自上而下)

除非现有文件已有更强的本地约定需要保留,否则强制遵循以下顺序:环境属性;private/public let;@State 及其他存储属性;计算属性(非视图);init;body;计算视图构建器及其他视图辅助;辅助/异步函数。

默认采用 MV,而非 MVVM

视图应当是轻量的状态表达与编排点,而不是业务逻辑的容器。优先使用 @State、@Environment、@Query、.task、.task(id:) 和 onChange,之后才考虑 view model。通过 @Environment 注入服务和共享模型;把领域逻辑保留在 service/model 中,而不是视图 body 里。不要仅为镜像局部视图状态或包装环境依赖而引入 view model。如果屏幕变得过大,应先拆分为子视图,而不是发明新的 view model 层。

优先使用独立子视图类型而非计算 some View 辅助

标记超过约一个屏幕高度或包含多个逻辑分段的 body 属性。对于非平凡的分段,优先抽出独立的 View 类型,尤其是当它们带有状态、异步工作、分支,或值得拥有自己的 preview 时。保持计算 some View 辅助罕见且小;不要用 private var header: some View 之类的片段搭建整个屏幕。向抽取出的子视图传入小而明确的输入(数据、绑定、回调),而不是把整个父级状态传下去。若抽取出的子视图变得可复用或独立有意义,就把它移到单独文件中。技能给出了推荐写法(如 HeaderSection、FilterSection、ResultsSection、FooterSection 等独立类型)与应避免的写法(用 header、filters、results、footer 等计算属性拼装 body)。

将动作和副作用抽离出 body

不要在视图 body 中内联非平凡按钮动作。不要把业务逻辑埋在 .task、.onAppear、.onChange 或 .refreshable 中。优先从视图调用小的私有方法,并把真正的业务逻辑移入 service/model。body 读起来应像 UI,而不是像 view controller。技能给出示例:按钮使用 action: save,.task(id: searchText) 调用 await reload(for:),而 save() 和 reload(for:) 作为私有方法存在。

保持稳定的视图树

避免 body 或计算视图通过 if/else 返回完全不同的根分支。优先使用单一稳定基础视图,把条件放在分段/修饰符内部(overlay、opacity、disabled、toolbar 等)。根部条件分支切换会导致 identity 变动、更大范围的失效与额外重算。技能给出推荐写法(List 内条件放在 toolbar 中)与应避免的写法(在 documentsListView 中根据 canEdit 返回 editableDocumentsList 或 readOnlyDocumentsList)。

view model 处理

仅当已经存在或明确被要求时才处理 view model。将 view model 视为遗留或明确需求模式,而非默认。除非请求或现有代码明确要求,不要引入 view model。若 view model 已存在,尽可能使其非可选。通过 init 向视图传递依赖,再在视图的 init 中创建 view model。避免 bootstrapIfNeeded 之类的延迟设置变通做法。技能给出基于 Observation 的示例:使用 @State private var viewModel,并在 init 中通过 _viewModel = State(initialValue: SomeViewModel(dependency: dependency)) 初始化。

Observation 用法

对于 iOS 17+ 上使用 @Observable 的引用类型,在拥有它的视图中以 @State 存储。显式向下传递 observable,避免可选状态,除非 UI 确实需要。若部署目标包含 iOS 16 或更早,在拥有者处使用 @StateObject,注入遗留 observable 模型时使用 @ObservedObject。

使用方式

技能提供的工作流为:按排序规则重排视图;从 body 中移除内联动作与副作用,把业务逻辑移入 service/model,视图中只保留轻量编排;通过抽取独立子视图类型来缩短过长的 body,避免用许多计算 some View 辅助重建屏幕;确保稳定的视图结构,避免根部 if 分支切换,把条件移到局部化分段/修饰符;若 view model 已存在或被明确要求,将可选 view model 替换为在 init 中初始化的非可选 @State view model;确认 Observation 用法(iOS 17+ 根 @Observable 模型用 @State,仅在部署目标要求时使用遗留包装);保持行为不变,除非被请求,不更改布局或业务逻辑。

适用场景

适用于拆分大型 SwiftUI 视图、整理数据流、清理 Observation 所有权等重构任务。

限制与注意事项

准则要求优先小而明确的视图类型,而非大型条件块和大型计算 some View 属性。计算视图构建器应位于 body 之下,非视图计算属性应位于 init 之上。一次好的 SwiftUI 重构应让视图自上而下读起来像数据流加布局,而不是布局与命令式逻辑混杂。技能提到 MV 优先的指导与理由可参见 references/mv-patterns.md。此外,当 SwiftUI API、Observation 行为或平台指南可能已变化时,应使用网络搜索查阅当前 Apple 开发者文档。

对于大型视图文件:当 SwiftUI 视图文件超过约 300 行时,应积极拆分。把有意义的分段抽成独立 View 类型,而不是把复杂度藏在许多计算属性中。可使用带 // MARK: - 注释的 private extension 放置动作与辅助,但不要把 extension 当作把巨型屏幕拆成更小视图类型的替代品。若抽取出的子视图被复用或独立有意义,就把它移到自己的文件中。