From swiftui
Quick reference for choosing and implementing iOS-native SwiftUI components, layouts, forms, lists, tabs, sheets, alerts, and toolbars.
How this skill is triggered — by the user, by Claude, or both
Slash command
/swiftui:beepus-maximus-swiftui-componentsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Quick reference for iOS 26+ SwiftUI components with HIG-compliant values, common aliases, and concrete best practices. Use this to pick the right component and implement it correctly the first time.
Quick reference for iOS 26+ SwiftUI components with HIG-compliant values, common aliases, and concrete best practices. Use this to pick the right component and implement it correctly the first time.
references/components.md for the full 50+ reference| User says | Maps to |
|---|---|
| popup, modal, bottom sheet, drawer | Sheet / FullScreenCover |
| dialog, confirmation, destructive action | Alert / ConfirmationDialog |
| list, table view, rows, cells | List / Form |
| tabs, tab bar, bottom nav | TabView |
| sidebar, split view, master-detail, two-column | NavigationSplitView |
| nav, navigation, drill-down, push | NavigationStack |
| grid, collection view, tiles, mosaic | LazyVGrid / LazyHGrid / Grid |
| dropdown, select, segmented, wheel | Picker |
| menu, long press menu, right-click | Menu / ContextMenu |
| toolbar, nav bar buttons, top bar | ToolbarItem |
| search, search bar, filter | .searchable modifier |
| empty state, no results, placeholder | ContentUnavailableView |
| loading, spinner, progress bar | ProgressView |
| toggle, switch, checkbox | Toggle |
| slider, range | Slider |
| date, time, calendar | DatePicker |
| text field, input, type text | TextField / TextEditor |
| image from URL, remote image | AsyncImage |
| photo library, camera roll | PhotosPicker |
| expandable, collapsible, accordion | DisclosureGroup |
| share, share sheet | ShareLink |
| inspector, detail panel, side panel | Inspector |
Also known as: table view, rows, cells, UITableView When to use: Displaying scrollable collections of similar items with standard row layout. Key rules:
Section for grouped content; always provide headers for accessibility.listStyle(.insetGrouped) for settings-like screens, .plain for data-heavy screens.swipeActions for row actions, not custom gesture hacks
Common mistake: Wrapping List in ScrollView — List already scrolls. Double-nesting causes broken layout.Also known as: settings, preferences, input form When to use: Collecting user input in a structured settings-like layout. Key rules:
Section with descriptive headers and footersAlso known as: nav, navigation, drill-down, push, UINavigationController When to use: Linear navigation flows where users push/pop views. Key rules:
navigationDestination(for:) — never NavigationLink(destination:)@State private var path = NavigationPath() for programmatic navigation.navigationTitle() and .navigationBarTitleDisplayMode(.inline) or .large explicitly
Common mistake: Putting NavigationStack inside a child view instead of at the root of a tab.Also known as: sidebar, split view, master-detail, two-column, three-column When to use: Multi-column layouts — sidebar + detail on iPad, collapses to stack on iPhone. Key rules:
.navigationSplitViewColumnWidth(min:ideal:max:) for column sizingAlso known as: tabs, tab bar, bottom nav, UITabBarController When to use: Top-level app sections (max 5 visible tabs). Key rules:
Tab("Title", systemImage:) syntax with SF Symbols.badge() for notification counts.toolbar(.hidden, for: .tabBar) when it should stay visible.Also known as: modal, bottom sheet, popup, drawer, half-sheet When to use: Presenting focused tasks, creation flows, or supplementary content. Key rules:
.presentationDetents([.medium, .large]) for resizable sheets.presentationDetents([.fraction(0.4)]) or .height(300).presentationDragIndicator(.visible) when sheet is resizable@Environment(\.dismiss) private var dismiss.fullScreenCover when .sheet with detents would be less disruptive.Also known as: dialog, popup, warning, error dialog When to use: Critical information requiring acknowledgment, or simple yes/no decisions. Key rules:
.destructive role, place on the left.cancel role, system positions it automaticallyAlso known as: action sheet, confirmation, destructive action prompt When to use: Confirming destructive actions or choosing from 3+ options. Key rules:
.cancel role button (system provides one, but be explicit).destructive role for dangerous actions — it renders red automaticallyAlso known as: dropdown menu, overflow menu, more menu, ellipsis menu When to use: Exposing secondary actions from a button tap. Key rules:
Label("Title", systemImage:) for menu items with iconsMenu("Title") { } primaryAction: { } to give the button a default tapAlso known as: long-press menu, right-click menu, peek menu When to use: Surfacing secondary actions on long-press of content. Key rules:
contextMenu { } modifier on the target viewcontextMenu { } preview: { } for rich previewsAlso known as: scroll container, scrollable area When to use: Custom scrollable layouts that aren't List-shaped. Key rules:
.scrollTargetBehavior(.viewAligned) for paging/snappingScrollViewReader + .scrollTo(id:) for programmatic scrollingLazyVStack(pinnedViews: [.sectionHeaders]) for sticky headers.horizontal, .vertical, or [.horizontal, .vertical]
Common mistake: Using ScrollView + ForEach for simple lists — use List instead for free cell recycling.Also known as: grid, collection view, tiles, mosaic When to use: Two-dimensional grid layouts with vertical scrolling. Key rules:
[GridItem]: .fixed(size), .flexible(min:max:), .adaptive(minimum:).adaptive(minimum: 150) for responsive column countLazyHGrid for horizontal grids with row definitions
Common mistake: Using Grid (fixed, non-lazy) when content count is dynamic — use LazyVGrid.Also known as: horizontal grid, horizontal collection When to use: Horizontal scrolling grids (e.g., category rows). Key rules:
[GridItem], wrap in ScrollView(.horizontal)Also known as: tap target, CTA, action button When to use: Any tappable action trigger. Key rules:
.buttonStyle(.borderedProminent) for primary CTA, .bordered for secondaryrole: .destructive for delete/remove actionscontrolSize: .large for prominent actions, .small for inline.disabled(condition) — never hide buttons that might exist
Common mistake: Custom button styles without 44pt minimum hit area.Also known as: switch, checkbox, on/off When to use: Binary on/off settings. Key rules:
.toggleStyle(.switch) explicitly outside Form if needed.toggleStyle(.checkbox) (macOS) — iOS uses switchAlso known as: dropdown, select, segmented control, wheel, menu picker When to use: Selecting one option from a predefined set. Key rules:
.pickerStyle(.segmented) for 2-4 visible options inline.pickerStyle(.menu) for compact dropdown.pickerStyle(.wheel) only for very specific cases (time-like selection).wheel style for short option lists — use .menu or .segmented.Also known as: range slider, scrubber When to use: Selecting a value within a continuous range. Key rules:
in: range and step: for discrete valuesminimumValueLabel and maximumValueLabel for range contextAlso known as: date selector, calendar picker, time picker When to use: Selecting dates, times, or date-time combinations. Key rules:
displayedComponents: to show .date, .hourAndMinute, or both.datePickerStyle(.graphical) for full calendar viewin: range for valid date ranges
Common mistake: Allowing unbounded date ranges when business logic requires constraints.Also known as: empty state, no results, placeholder, zero state When to use: When a view has no content to display (empty list, no search results, error). Key rules:
ContentUnavailableView.search for empty search results (built-in)Also known as: loading, spinner, progress bar, activity indicator When to use: Indicating loading or operation progress. Key rules:
ProgressView() — spinning indicatorProgressView(value: 0.5) — progress bar, value 0.0-1.0.progressViewStyle(.circular) or .linear explicitly when neededProgressView("Loading data...")
Common mistake: Showing a spinner for < 200ms operations — use task with a delay threshold.For the complete 50+ component reference including Navigation, Presentation, Content, Controls, Feedback, Menus, Media, and Search categories with full code examples, decision tables, and anti-patterns, read references/components.md.
When multiple components could work, here are the fastest correct choices:
| Situation | Shortest Path |
|---|---|
| "I need a settings screen" | Form with Section, Toggle, Picker |
| "I need a data list" | List with .insetGrouped, swipeActions |
| "I need a grid of items" | ScrollView + LazyVGrid with .adaptive(minimum:) |
| "I need to collect input" | Sheet with Form inside |
| "I need to show detail" | navigationDestination(for:) push |
| "I need to confirm delete" | ConfirmationDialog with .destructive role |
| "I need empty state" | ContentUnavailableView with icon + description + action |
| "I need tabs" | TabView with NavigationStack per tab |
| Rule | Value |
|---|---|
| Minimum touch target | 44x44pt |
| Spacing scale | 4, 8, 12, 16, 24, 32 pt |
| Corner radius style | .continuous (never .circular) |
| Animation for controls | .spring(duration: 0.3, bounce: 0) |
| Animation for content | .spring(duration: 0.35, bounce: 0.1) |
| List row minimum height | 44pt |
| List row with subtitle | 60pt typical |
| Tab bar max visible items | 5 |
| Deployment target | iOS 26+ only — no @available checks, no deprecated APIs |
| NavigationView | BANNED — use NavigationStack or NavigationSplitView |
| NavigationLink(destination:) | BANNED — use navigationDestination(for:) |
.presentationDetents behave differently on iPad (sheets are popovers by default). Test on both..pickerStyle(.menu) it overrides this, which may not be what you want.Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub 4eleven7/claude-skills --plugin swiftui