Native swiftui
Build iOS apps that look and behave like native Apple software by preferring highest-level SwiftUI components, system styles, semantic colors, and standard navigation structures. Use when creating or reviewing SwiftUI UI, choosing between custom vs built-in controls, styling buttons and cards, or when the user wants a native iOS look, HIG-aligned layouts, or out-of-the-box SwiftUI APIs instead of custom implementations.From its SKILL.md
npx -y skills add dbmrq/agent-skills --skill native-swiftuiAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.4 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
Native SwiftUI
Produce iOS interfaces that feel native by defaulting to Apple's ready-made SwiftUI components and styles before writing custom views. Custom UI is the exception, not the starting point.
Skill split:
native-swiftui(this skill) — what Apple components and system styles to useswiftui-view-composition— how to structure and refactor large views into reusable piecesswiftui-project-structure— repo folders, packages, targets, MV vs Store layersswiftui-expert-skill— state, performance, concurrency (avdlee/swiftui-agent-skill; install via./scripts/install-all.sh)
Agent workflow
- Check deployment target — use the newest APIs the minimum iOS version supports.
- Pick structure first —
NavigationStack/NavigationSplitView+.inspectorbefore inventing custom chrome. - Pick components second — scan built-in-components.md for a system control that fits.
- Style at the root —
.tint,.buttonStyle,.groupBoxStyleonWindowGroupor screen containers (see styling.md). - Verify native feel — system colors, SF Symbols, Dynamic Type, Dark Mode, accessibility labels.
- Reject custom reimplementations — if Apple ships it, use it.
- Structure large screens — if
bodyis hard to scan, applyswiftui-view-composition(extractViewstructs before custom modifiers).
Golden rules
| Prefer | Avoid |
|---|---|
GroupBox, Form, DisclosureGroup for grouped content | Custom RoundedRectangle + shadow "cards" |
.buttonStyle(.borderedProminent) / .bordered + ButtonRole | Hand-rolled button backgrounds and borders |
Semantic colors (.primary, .secondary, .tint, .teal, .mint) | Hard-coded hex/RGB/Color(red:green:blue:) |
Label, LabeledContent for icon+text rows | Manual HStack of Image + Text |
ContentUnavailableView for empty states | Custom empty-state illustrations |
NavigationStack, NavigationSplitView, .inspector | Custom nav bars, sidebars, detail panes |
ShareLink, ColorPicker, PasteButton, RenameButton | UIKit bridges or bespoke controls |
| SF Symbols | Custom icon assets (unless branding requires) |
@Observable + @State | ObservableObject / @Published in new code |
.task / .task(id:) | onAppear { Task { } } without cancellation |
App structure and navigation
iPhone
NavigationStackfor drill-down flows;navigationDestination(for:)for type-safe pushes.TabViewwith theTabAPI (not deprecatedtabItem)..sheet(item:)for model-driven modals; sheet content owns its actions and callsdismiss().
iPad / macOS
NavigationSplitViewfor sidebar + detail; add.inspectorfor supplementary panels (settings, metadata, tools) instead of a third custom column.- Use size classes and
horizontalSizeClassto adapt compact vs regular layouts. ViewThatFitswhen a row may need to collapse to a column on narrow widths.
NavigationSplitView {
List(selection: $selection) { /* sidebar */ }
} detail: {
DetailView(item: selection)
.inspector(isPresented: $showInspector) {
InspectorPanel()
}
}
Settings and forms
Formfor settings screens and data entry.- Nest
GroupBoxinsideFormor otherGroupBoxviews for logical sections — the system alternates backgrounds per nesting level automatically. DisclosureGroupfor expandable settings sections.LabeledContentfor label/value rows (settings detail, read-only info).
Visual grouping
Use Apple's grouping primitives — they carry correct spacing, materials, and accessibility:
GroupBox("Account") {
LabeledContent("Username") { Text(user.name) }
LabeledContent("Plan") { Text(user.plan) }
}
DisclosureGroup("Advanced") {
Toggle("Analytics", isOn: $analytics)
}
ControlGroupfor related actions (media transport, toolbar-like button clusters).OutlineGroupfor hierarchical tree data in lists.Labeleverywhere icons accompany text (lists, buttons, menus).
Buttons and controls
Apply styles once at a container or app root; do not wrap Button in custom MyButton types.
// App root
ContentView()
.tint(.teal)
.buttonStyle(.borderedProminent)
// Destructive actions
Button(role: .destructive) { delete() } label: {
Label("Delete", systemImage: "trash")
}
// Secondary actions
Button("Cancel", role: .cancel) { dismiss() }
.buttonStyle(.bordered)
- Roles:
.destructivefor delete/remove,.cancelfor dismissive actions. - Prominence:
.borderedProminentfor primary CTA;.borderedor.borderlessfor secondary. Stepper,Gauge,Picker,Toggle,Slider— use as-is; apply.pickerStyle(.segmented)etc. at the group level.ShareLinkfor sharing URLs, text, or images — notUIActivityViewControllerwrappers.
Colors, materials, and typography
- Use semantic styles:
.foregroundStyle(.primary),.foregroundStyle(.secondary),.tint(.mint). - Use system palette names (
.teal,.mint,.indigo,.orange) for accents — they adapt to light/dark and accessibility settings. - Use
foregroundStyle()instead of deprecatedforegroundColor(). - Support Dynamic Type — avoid fixed font sizes for body text; use
.font(.body),.headline, etc. MeshGradientfor decorative backgrounds when a multi-point gradient is needed (iOS 18+); prefer materials (.regularMaterial) for functional surfaces.
State, concurrency, and data
From project-wide Swift guidelines:
@Observablefor shared model state;@Stateto own it in a view;@Bindablefor bindings to injected observables.@MainActoron types that drive UI; keep non-UI work off the main actor.async/awaitwith strict concurrency; actors for shared mutable state.- Storage:
UserDefaults(simple prefs), Keychain (secrets), SwiftData (models), CloudKit (sync) — match the problem, don't invent file formats. Loggerinstead ofprint(); no forced unwraps (!).
Animation and live content
TimelineViewfor clocks, countdowns, or periodic refresh (weather, timers) — notTimer+@Statepolling.PhaseAnimatorfor repeating multi-phase animations (pulse, shimmer) — not manual animation loops.ScenePhasevia@Environment(\.scenePhase)for foreground/background lifecycle in views.
Accessibility and platform
- VoiceOver labels and hints on all interactive elements from the start.
- Dark Mode must work without separate color definitions when using semantic colors.
- Follow Human Interface Guidelines and App Store Review expectations.
- Add Previews to every view; use
#Previewwith varied size classes when layout adapts.
Custom UI — only when necessary
Reach for custom views only after confirming no built-in fits:
| Need | Built-in first |
|---|---|
| Card / panel | GroupBox |
| Empty list | ContentUnavailableView |
| Expandable section | DisclosureGroup |
| Icon + title row | Label / LabeledContent |
| Tree list | OutlineGroup |
| Adaptive H/V layout | ViewThatFits |
| Custom arrangement | Layout protocol (not nested stacks with magic numbers) |
| Drawing / charts | Canvas (not UIViewRepresentable unless required) |
| Map | SwiftUI Map + MapKit |
| Multi-date selection | MultiDatePicker |
| Clipboard paste | PasteButton |
| Inline rename | RenameButton |
| Per-corner radius | UnevenRoundedRectangle |
Full catalog with usage notes: built-in-components.md.
Styling system components
- Set
.buttonStyle,.tint,.toggleStyle,.pickerStyleonWindowGroupor screen root — styles propagate like environment values. - Extend built-in styles with
Button(configuration)/ style-configuration initializers instead of per-button modifier stacks. - Nested
GroupBoxdoes not inherit a custom.groupBoxStylefrom its parent — reapply inside the style'smakeBodyor on each nested box. Prefer the default automatic style unless branding requires custom. - Sheets may not inherit styles from the presenter — reapply styles on sheet content when needed.
Details: styling.md.
Code quality checklist
Before finishing UI work:
- No custom card/button when
GroupBox/.borderedProminentsuffices - No hard-coded RGB/hex colors for standard UI
- Navigation uses
NavigationStackorNavigationSplitView(not legacyNavigationView) - Empty states use
ContentUnavailableView - Icons are SF Symbols with appropriate rendering mode
- Forms and settings use
Form+LabeledContent/DisclosureGroup - Primary actions use
.borderedProminent; destructive userole: .destructive - Styles applied at root, not duplicated on every control
- Previews present; Dynamic Type and Dark Mode spot-checked
- Accessibility labels set on custom-labeled controls
View structure
This skill does not cover refactoring large view bodies. When a screen grows beyond a short, scannable body:
- Extract rows, sections, and states into dedicated
Viewstructs — not extension computed properties - Prefer
List/GroupBoxfor extracted pieces instead of custom card modifiers - See
swiftui-view-compositionfor the full extraction workflow, decision guide, and refactor patterns
Swift and project conventions
- One type per file; feature/domain folders (not global
Views//ViewModels/splits). For repo layout, packages, and architecture layers, seeswiftui-project-structure. // MARK: -sections; protocol conformance in extensions.- Swift Testing over XCTest for new tests; meaningful business-logic coverage.
- Remove stale code after refactors; match patterns already in the project.
- Do not add documentation files unless the user asks.
What ships with it: 2 files
10.5 KB alongside SKILL.md
- built-in-components.md5.5 KB
- styling.md5.0 KB