Skip to main content

swiftui-view-refactor

SwiftUI view refactor/review: layout, DI, Observation, view models.

Quellinformationen

Repository
steipete/agent-scripts
Letzte Quellaktivität
23. Mai 2026 um 08:13
Erkannte Sprache von SKILL.md
Englisch
Sterne
7.483
Forks
651

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
swiftui-view-refactor
description
SwiftUI view refactor/review: layout, DI, Observation, view models.
# 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): ```swift 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): ```swift 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): ```swift 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): ```swift @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`.
Auf GitHub ansehen