swiftui-ui-patterns

Phase 3 (Implement — best practices, UI architecture) and Phase 5 (Review — checklist). Core guidelines apply during implementation; review checklist during code review.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "swiftui-ui-patterns" with this command: npx skills add kmshdev/claude-swift-toolkit/kmshdev-claude-swift-toolkit-swiftui-ui-patterns

SwiftUI UI Patterns

Lifecycle Position

Phase 3 (Implement — best practices, UI architecture) and Phase 5 (Review — checklist). Core guidelines apply during implementation; review checklist during code review.

When to Use

digraph when { rankdir=TB; node [fontsize=11];

Q [label="What are you building?" shape=diamond]; A1 [label="New SwiftUI view" shape=box]; A2 [label="Reviewing code" shape=box]; A3 [label="App shell / navigation" shape=box]; A4 [label="Specific UI component" shape=box]; B1 [label="Read Core Guidelines\nthen Quick Reference table" shape=box style=filled fillcolor=lightblue]; B2 [label="Use Review Checklist\nat bottom of this file" shape=box style=filled fillcolor=lightblue]; B3 [label="app-wiring.md → navigation.md\n→ sheets-and-routing.md" shape=box style=filled fillcolor=lightblue]; B4 [label="Find component in\nQuick Reference table" shape=box style=filled fillcolor=lightblue];

Q -> A1 [label="feature"]; Q -> A2 [label="review"]; Q -> A3 [label="scaffold"]; Q -> A4 [label="component"];

A1 -> B1; A2 -> B2; A3 -> B3; A4 -> B4; }

Quick Reference — Which Reference to Load

UI Need Reference File

App root shell, TabRouter, dependency graph references/app-wiring.md

Tab architecture, AppTab enum, TabSection references/tabview.md

NavigationStack routing, RouterPath references/navigation.md

Sheet presentation, SheetDestination enum references/sheets-and-routing.md

Lists, ForEach identity, scroll-to-top references/lists.md

ScrollView, chat anchor, horizontal chips references/scroll-patterns.md

LazyVGrid, adaptive/fixed columns references/grids.md

Forms, themed modals, auto-focus references/forms-and-input.md

.searchable, async debounced search references/searchable.md

Toast overlay, auto-dismiss banners references/overlay-toast.md

Bottom composer bar, .safeAreaInset references/input-toolbar.md

iOS 26+ safeAreaBar, top bar references/top-bar.md

@Observable Theme, semantic colors references/theming.md

AsyncImage, QuickLook media viewer references/image-and-media.md

Haptic feedback, HapticManager references/haptics.md

withAnimation, .animation modifier, CustomAnimation references/state-based-animation.md

Keyframe animations, KeyframeTimeline references/keyframe-animation.md

View transitions, matchedTransitionSource, zoom references/view-transitions.md

Transaction control, TransactionKey references/transactions.md

matchedGeometryEffect, geometryGroup references/geometry-sync.md

Animatable protocol, VectorArithmetic references/animatable-data.md

TimelineView, scheduled updates references/timeline-view.md

PhaseAnimator, multi-step sequences references/phase-animation.md

Spring parameters, UnitCurve timing references/timing-and-curves.md

Deep links, URL dispatch, OpenURLAction references/deeplinks.md

ToolbarTitleMenu, principal title references/title-menus.md

NavigationSplitView vs manual split references/split-views.md

.redacted placeholders, ContentUnavailableView references/loading-placeholders.md

Closure-based client struct, store DI references/lightweight-clients.md

Modern API replacements, deprecations references/modern-apis.md

Property wrappers, @Observable, data flow references/state-management.md

View extraction, composition rules references/view-structure.md

Performance optimization, body purity references/performance-patterns.md

Layout patterns, context-agnostic views references/layout-best-practices.md

Text formatting, localizedStandardContains references/text-formatting.md

Templates

Deep linking and App Shortcuts in templates/ — copy and adapt:

  • DeepLink.swift — URL-to-enum parser for typed deep link handling

  • DeepLinkRouter.swift — @MainActor @Observable navigation router with pending link support, NavigationPath integration, EnvironmentKey injection

  • AppShortcuts.swift — Siri App Intents / App Shortcuts for voice and Spotlight integration

  • apple-app-site-association — Universal Links JSON template for your domain

Core Guidelines

State Management

  • Always prefer @Observable over ObservableObject for new code

  • Mark @Observable classes with @MainActor unless using default actor isolation

  • Always mark @State and @StateObject as private (makes dependencies clear)

  • Never declare passed values as @State or @StateObject

  • @State for internal view state, or owned @Observable class

  • @Binding only when child needs to modify parent state

  • @Bindable for injected @Observable objects needing bindings

  • Use let for read-only values; var

  • .onChange() for reactive reads
  • Nested ObservableObject doesn't work — pass nested objects directly; @Observable handles nesting

Modern APIs

  • foregroundStyle() not foregroundColor()

  • clipShape(.rect(cornerRadius:)) not cornerRadius()

  • Tab API not tabItem()

  • Button not onTapGesture() (unless need location/count)

  • NavigationStack not NavigationView

  • navigationDestination(for:) for type-safe navigation

  • Two-parameter onChange(of:) { old, new in } or no-parameter variant

  • .sheet(item:) not .sheet(isPresented:) for model-based sheets

  • Sheets own their actions and call dismiss() internally

  • containerRelativeFrame() or visualEffect() over GeometryReader

  • .scrollIndicators(.hidden) not showsIndicators: false

  • Avoid UIScreen.main.bounds for sizing

Swift Best Practices

  • Use modern Text formatting (.format parameters, not String(format:) )

  • Use localizedStandardContains() for user-input filtering

  • Use .task modifier for automatic cancellation of async work

  • Use .task(id:) for value-dependent async tasks

View Composition

  • Prefer modifiers over conditional views for state changes (maintains view identity)

  • Extract complex views into separate subviews early

  • Keep view body simple and pure (no side effects or complex logic)

  • Use @ViewBuilder let content: Content over closure-based content properties

  • Separate business logic into testable models

  • Action handlers should reference methods, not contain inline logic

  • Use relative layout over hard-coded constants

  • Views should work in any context (context-agnostic)

Performance

  • Pass only needed values to views (not large "config" or "context" objects)

  • LazyVStack /LazyHStack for large lists

  • Stable identity for ForEach (never .indices for dynamic content)

  • Constant number of views per ForEach element

  • No inline filtering in ForEach (prefilter and cache)

  • No AnyView in list rows

  • Check for value changes before assigning state in hot paths

  • No object creation in body

Liquid Glass (iOS 26+)

Only adopt when explicitly requested.

  • Use glassEffect , GlassEffectContainer , glass button styles

  • Apply .glassEffect() after layout and visual modifiers

  • Gate with #available(iOS 26, *) and provide fallbacks

  • Use glassEffectID with @Namespace for morphing transitions

  • See apple-liquid-glass-design skill for full glass API reference

Review Checklist

State Management (see references/state-management.md )

  • Using @Observable instead of ObservableObject for new code

  • @Observable classes marked with @MainActor (if needed)

  • Using @State with @Observable classes (not @StateObject )

  • @State and @StateObject properties are private

  • Passed values NOT declared as @State or @StateObject

  • @Binding only where child modifies parent state

  • @Bindable for injected @Observable needing bindings

  • Nested ObservableObject avoided (or passed directly to child views)

Modern APIs (see references/modern-apis.md )

  • Using foregroundStyle() instead of foregroundColor()

  • Using clipShape(.rect(cornerRadius:)) instead of cornerRadius()

  • Using Tab API instead of tabItem()

  • Using Button instead of onTapGesture() (unless need location/count)

  • Using NavigationStack instead of NavigationView

  • Avoiding UIScreen.main.bounds

  • Using alternatives to GeometryReader when possible

  • Button images include text labels for accessibility

Sheets & Navigation (see references/sheets-and-routing.md , references/navigation.md )

  • Using .sheet(item:) for model-based sheets

  • Sheets own their actions and dismiss internally

  • Using navigationDestination(for:) for type-safe navigation

ScrollView (see references/scroll-patterns.md )

  • Using ScrollViewReader with stable IDs for programmatic scrolling

  • Using .scrollIndicators(.hidden) instead of initializer parameter

Text & Formatting (see references/text-formatting.md )

  • Using modern Text formatting (not String(format:) )

  • Using localizedStandardContains() for search filtering

View Structure (see references/view-structure.md )

  • Using modifiers instead of conditionals for state changes

  • Complex views extracted to separate subviews

  • Views kept small for performance

  • Container views use @ViewBuilder let content: Content

Performance (see references/performance-patterns.md )

  • View body kept simple and pure (no side effects)

  • Passing only needed values (not large config objects)

  • Eliminating unnecessary dependencies

  • State updates check for value changes before assigning

  • Hot paths minimize state updates

  • No object creation in body

  • Heavy computation moved out of body

List Patterns (see references/lists.md )

  • ForEach uses stable identity (not .indices )

  • Constant number of views per ForEach element

  • No inline filtering in ForEach

  • No AnyView in list rows

Layout (see references/layout-best-practices.md )

  • Avoiding layout thrash (deep hierarchies, excessive GeometryReader)

  • Gating frequent geometry updates by thresholds

  • Business logic separated into testable models

  • Action handlers reference methods (not inline logic)

  • Using relative layout (not hard-coded constants)

  • Views work in any context (context-agnostic)

Animations (see references/state-based-animation.md , references/view-transitions.md , references/keyframe-animation.md )

  • Using .animation(_:value:) with value parameter

  • Using withAnimation for event-driven animations

  • Transitions paired with animations outside conditional structure

  • Custom Animatable has explicit animatableData implementation

  • Preferring transforms over layout changes for animation performance

  • Phase animations for multi-step sequences (iOS 17+)

  • Keyframe animations for precise timing (iOS 17+)

  • Completion handlers use .transaction(value:) for reexecution

Liquid Glass (iOS 26+)

  • #available(iOS 26, *) with fallback for Liquid Glass

  • Multiple glass views wrapped in GlassEffectContainer

  • .glassEffect() applied after layout/appearance modifiers

  • .interactive() only on user-interactable elements

  • Shapes and tints consistent across related elements

Cross-References

  • apple-liquid-glass-design — Full Liquid Glass API reference, glass button styles, morph transitions

  • swift-concurrency — Actors, @MainActor , Sendable , SwiftUI concurrency patterns

  • swift-app-lifecycle — Scene structure, app entry points (pairs with app-wiring.md , deeplinks.md )

  • swift-networking — Async network patterns (pairs with references/lightweight-clients.md )

  • swiftui-26-api — Non-glass iOS 26 APIs (WebView, TextEditor rich text, @Animatable)

  • swiftui-input-api — Text fields, pickers, controls, focus management (pairs with references/searchable.md , references/forms-and-input.md )

  • swiftui-material-api — Material backgrounds, shapes, stroke patterns

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.

Coding

swiftui-26-api

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

swift-concurrency

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

swift-actor-persistence

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

swiftui-iconography-api

No summary provided by upstream source.

Repository SourceNeeds Review