swiftui-view-refactor

Refactor and review SwiftUI view files for consistent structure, dependency injection, and Observation usage. Use when asked to clean up a SwiftUI view’s layout/ordering, handle view models safely (non-optional when possible), or standardize how dependencies and @Observable state are initialized and passed.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "swiftui-view-refactor" with this command: npx skills add steipete/swiftui-view-refactor

SwiftUI View Refactor

Attribution: copied from @Dimillian’s Dimillian/Skills (2025-12-31).

Overview

Apply a consistent structure and dependency pattern to SwiftUI views, with a focus on ordering, Model-View (MV) patterns, careful view model handling, and correct Observation usage.

Core Guidelines

1) View ordering (top → bottom)

  • Environment
  • private/public let
  • @State / other stored properties
  • computed var (non-view)
  • init
  • body
  • computed view builders / other view helpers
  • helper / async functions

2) Prefer MV (Model-View) patterns

  • Default to MV: Views are lightweight state expressions; models/services own business logic.
  • Favor @State, @Environment, @Query, and task/onChange for orchestration.
  • Inject services and shared models via @Environment; keep views small and composable.
  • Split large views into subviews rather than introducing a view model.

3) Split large bodies and view properties

  • If body grows beyond a screen or has multiple logical sections, split it into smaller subviews.
  • Extract large computed view properties (var header: some View { ... }) into dedicated View types when they carry state or complex branching.
  • It's fine to keep related subviews as computed view properties in the same file; extract to a standalone View struct only when it structurally makes sense or when reuse is intended.
  • Prefer passing small inputs (data, bindings, callbacks) over reusing the entire parent view state.

Example (extracting a section):

var body: some View {
    VStack(alignment: .leading, spacing: 16) {
        HeaderSection(title: title, isPinned: isPinned)
        DetailsSection(details: details)
        ActionsSection(onSave: onSave, onCancel: onCancel)
    }
}

Example (long body → shorter body + computed views in the same file):

var body: some View {
    List {
        header
        filters
        results
        footer
    }
}

private var header: some View {
    VStack(alignment: .leading, spacing: 6) {
        Text(title).font(.title2)
        Text(subtitle).font(.subheadline)
    }
}

private var filters: some View {
    ScrollView(.horizontal, showsIndicators: false) {
        HStack {
            ForEach(filterOptions, id: \.self) { option in
                FilterChip(option: option, isSelected: option == selectedFilter)
                    .onTapGesture { selectedFilter = option }
            }
        }
    }
}

Example (extracting a complex computed view):

private var header: some View {
    HeaderSection(title: title, subtitle: subtitle, status: status)
}

private struct HeaderSection: View {
    let title: String
    let subtitle: String?
    let status: Status

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(title).font(.headline)
            if let subtitle { Text(subtitle).font(.subheadline) }
            StatusBadge(status: status)
        }
    }
}

4) View model handling (only if already present)

  • Do not introduce a view model unless the request or existing code clearly calls for one.
  • If a view model exists, make it non-optional when possible.
  • Pass dependencies to the view via init, then pass them into the view model in the view's init.
  • Avoid bootstrapIfNeeded patterns.

Example (Observation-based):

@State private var viewModel: SomeViewModel

init(dependency: Dependency) {
    _viewModel = State(initialValue: SomeViewModel(dependency: dependency))
}

5) Observation usage

  • For @Observable reference types, store them as @State in the root view.
  • Pass observables down explicitly as needed; avoid optional state unless required.

Workflow

  1. Reorder the view to match the ordering rules.
  2. Favor MV: move lightweight orchestration into the view using @State, @Environment, @Query, task, and onChange.
  3. If a view model exists, replace optional view models with a non-optional @State view model initialized in init by passing dependencies from the view.
  4. Confirm Observation usage: @State for root @Observable view models, no redundant wrappers.
  5. Keep behavior intact: do not change layout or business logic unless requested.

Notes

  • Prefer small, explicit helpers over large conditional blocks.
  • Keep computed view builders below body and non-view computed vars above init.
  • For MV-first guidance and rationale, see references/mv-patterns.md.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Omniscient

全知全能技能 — 整合认知套件、执行框架、系统控制三大能力层,并配备编排引擎。 认知层:四种思维操作码(直用/改进/迁移/构建)覆盖所有思考任务; 执行层:大语言模型 + 命令执行工具,自动化代码生成与脚本执行; 操控层:Windows桌面软件、系统硬件、串口设备、物联网平台、图形界面自动化、蓝牙设备、GPU显卡...

Registry SourceRecently Updated
General

系统清理技能

定期清理OpenClaw系统中的备份、临时及会话文件,分析磁盘使用并检查系统状态,优化系统性能。

Registry SourceRecently Updated
General

Whoislookup

Look up domain WHOIS registration info — registrar, creation date, expiry date, nameservers, and domain status. Use when asked to check who owns a domain, wh...

Registry SourceRecently Updated
General

WayinVideo - Find Moments in the Video

Find specific moments in a video using a natural language query. Ideal for locating particular scenes, topics, or events in long videos (e.g., “the part wher...

Registry SourceRecently Updated