swiftui-expert-skill
SKILL.md
SwiftUI Expert Skill
Overview
Use this skill to build, review, or improve SwiftUI features with correct state management, optimal view composition, and iOS 26+ Liquid Glass styling. Prioritize native APIs, Apple design guidance, and performance-conscious patterns. This skill focuses on facts and best practices without enforcing specific architectural patterns.
Workflow Decision Tree
1) Review existing SwiftUI code
- First, consult
references/latest-apis.mdto ensure only current, non-deprecated APIs are used - Check property wrapper usage against the selection guide (see
references/state-management.md) - Verify view composition follows extraction rules (see
references/view-structure.md) - Check performance patterns are applied (see
references/performance-patterns.md) - Verify list patterns use stable identity (see
references/list-patterns.md) - Check animation patterns for correctness (see
references/animation-basics.md,references/animation-transitions.md) - Review accessibility: proper grouping, traits, Dynamic Type support (see
references/accessibility-patterns.md) - Inspect Liquid Glass usage for correctness and consistency (see
references/liquid-glass.md) - Validate iOS 26+ availability handling with sensible fallbacks
2) Improve existing SwiftUI code
- First, consult
references/latest-apis.mdto replace any deprecated APIs with their modern equivalents - Audit state management for correct wrapper selection (see
references/state-management.md) - Extract complex views into separate subviews (see
references/view-structure.md) - Refactor hot paths to minimize redundant state updates (see
references/performance-patterns.md) - Ensure ForEach uses stable identity (see
references/list-patterns.md) - Improve animation patterns (use value parameter, proper transitions, see
references/animation-basics.md,references/animation-transitions.md) - Improve accessibility: use
Buttonover tap gestures, add@ScaledMetricfor Dynamic Type (seereferences/accessibility-patterns.md) - Suggest image downsampling when
UIImage(data:)is used (as optional optimization, seereferences/image-optimization.md) - Adopt Liquid Glass only when explicitly requested by the user
3) Implement new SwiftUI feature
- First, consult
references/latest-apis.mdto use only current, non-deprecated APIs for the target deployment version - Design data flow first: identify owned vs injected state (see
references/state-management.md) - Structure views for optimal diffing (extract subviews early, see
references/view-structure.md) - Keep business logic in services and models for testability (see
references/layout-best-practices.md) - Use correct animation patterns (implicit vs explicit, transitions, see
references/animation-basics.md,references/animation-transitions.md,references/animation-advanced.md) - Use
Buttonfor tappable elements, add accessibility grouping and labels (seereferences/accessibility-patterns.md) - Apply glass effects after layout/appearance modifiers (see
references/liquid-glass.md) - Gate iOS 26+ features with
#availableand provide fallbacks
Core Guidelines
State Management
@Statemust beprivate; use for internal view state@Bindingonly when a child needs to modify parent state@StateObjectwhen view creates the object;@ObservedObjectwhen injected- iOS 17+: Use
@Statewith@Observableclasses; use@Bindablefor injected observables needing bindings - Use
letfor read-only values;var+.onChange()for reactive reads - Never pass values into
@Stateor@StateObject— they only accept initial values - Nested
ObservableObjectdoesn't propagate changes — pass nested objects directly;@Observablehandles nesting fine
View Composition
- Extract complex views into separate subviews for better readability and performance
- Prefer modifiers over conditional views for state changes (maintains view identity)
- Keep view
bodysimple and pure (no side effects or complex logic) - Use
@ViewBuilderfunctions only for small, simple sections - Prefer
@ViewBuilder let content: Contentover closure-based content properties - Keep business logic in services and models; views should orchestrate UI flow
- Action handlers should reference methods, not contain inline logic
- Views should work in any context (don't assume screen size or presentation style)
Performance
- Pass only needed values to views (avoid large "config" or "context" objects)
- Eliminate unnecessary dependencies to reduce update fan-out
- Check for value changes before assigning state in hot paths
- Avoid redundant state updates in
onReceive,onChange, scroll handlers - Minimize work in frequently executed code paths
- Use
LazyVStack/LazyHStackfor large lists - Use stable identity for
ForEach(never.indicesfor dynamic content) - Ensure constant number of views per
ForEachelement - Avoid inline filtering in
ForEach(prefilter and cache) - Avoid
AnyViewin list rows - Consider POD views for fast diffing (or wrap expensive views in POD parents)
- Suggest image downsampling when
UIImage(data:)is encountered (as optional optimization) - Avoid layout thrash (deep hierarchies, excessive
GeometryReader) - Gate frequent geometry updates by thresholds
- Use
Self._logChanges()orSelf._printChanges()to debug unexpected view updates
Animations
- Use
.animation(_:value:)with value parameter (deprecated version without value is too broad) - Use
withAnimationfor event-driven animations (button taps, gestures) - Prefer transforms (
offset,scale,rotation) over layout changes (frame) for performance - Transitions require animations outside the conditional structure
- Custom
Animatableimplementations must have explicitanimatableData - Use
.phaseAnimatorfor multi-step sequences (iOS 17+) - Use
.keyframeAnimatorfor precise timing control (iOS 17+) - Animation completion handlers need
.transaction(value:)for reexecution - Implicit animations override explicit animations (later in view tree wins)
Accessibility
- Prefer
ButtonoveronTapGesturefor tappable elements (free VoiceOver support) - Use
@ScaledMetricfor custom numeric values that should scale with Dynamic Type - Group related elements with
accessibilityElement(children: .combine)for joined labels - Provide
accessibilityLabelwhen default labels are unclear or missing - Use
accessibilityRepresentationfor custom controls that should behave like native ones
Liquid Glass (iOS 26+)
Only adopt when explicitly requested by the user.
- Use native
glassEffect,GlassEffectContainer, and glass button styles - Wrap multiple glass elements in
GlassEffectContainer - Apply
.glassEffect()after layout and visual modifiers - Use
.interactive()only for tappable/focusable elements - Use
glassEffectIDwith@Namespacefor morphing transitions
Quick Reference
Property Wrapper Selection
| Wrapper | Use When |
|---|---|
@State |
Internal view state (must be private) |
@Binding |
Child modifies parent's state |
@StateObject |
View owns an ObservableObject |
@ObservedObject |
View receives an ObservableObject |
@Bindable |
iOS 17+: Injected @Observable needing bindings |
let |
Read-only value from parent |
var |
Read-only value watched via .onChange() |
Liquid Glass Patterns
// Basic glass effect with fallback
if #available(iOS 26, *) {
content
.padding()
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
content
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
// Grouped glass elements
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
GlassButton1()
GlassButton2()
}
}
// Glass buttons
Button("Confirm") { }
.buttonStyle(.glassProminent)
Review Checklist
Latest APIs (see references/latest-apis.md)
- No deprecated modifiers used (check against the quick lookup table)
- API choices match the project's minimum deployment target
State Management
-
@Stateproperties areprivate -
@Bindingonly where child modifies parent state -
@StateObjectfor owned,@ObservedObjectfor injected - iOS 17+:
@Statewith@Observable,@Bindablefor injected - Passed values NOT declared as
@Stateor@StateObject - Nested
ObservableObjectavoided (or passed directly to child views)
Sheets & Navigation (see references/sheet-navigation-patterns.md)
- Using
.sheet(item:)for model-based sheets - Sheets own their actions and dismiss internally
ScrollView (see references/scroll-patterns.md)
- Using
ScrollViewReaderwith stable IDs for programmatic scrolling
View Structure (see references/view-structure.md)
- Using modifiers instead of conditionals for state changes
- Complex views extracted to separate subviews
- Container views use
@ViewBuilder let content: Content
Performance (see references/performance-patterns.md)
- View
bodykept 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/list-patterns.md)
- ForEach uses stable identity (not
.indices) - Constant number of views per ForEach element
- No inline filtering in ForEach
- No
AnyViewin list rows
Layout (see references/layout-best-practices.md)
- Avoiding layout thrash (deep hierarchies, excessive GeometryReader)
- Gating frequent geometry updates by thresholds
- Business logic kept in services and models (not in views)
- Action handlers reference methods (not inline logic)
- Using relative layout (not hard-coded constants)
- Views work in any context (context-agnostic)
Animations (see references/animation-basics.md, references/animation-transitions.md, references/animation-advanced.md)
- Using
.animation(_:value:)with value parameter - Using
withAnimationfor event-driven animations - Transitions paired with animations outside conditional structure
- Custom
Animatablehas explicitanimatableDataimplementation - 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
Accessibility (see references/accessibility-patterns.md)
-
Buttonused instead ofonTapGesturefor tappable elements -
@ScaledMetricused for custom values that should scale with Dynamic Type - Related elements grouped with
accessibilityElement(children:) - Custom controls use
accessibilityRepresentationwhen appropriate
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
References
references/latest-apis.md- Required reading for all workflows. Version-segmented guide of deprecated-to-modern API transitions (iOS 15+ through iOS 26+)references/state-management.md- Property wrappers and data flowreferences/view-structure.md- View composition, extraction, and container patternsreferences/performance-patterns.md- Performance optimization techniques and anti-patternsreferences/list-patterns.md- ForEach identity, stability, and list best practicesreferences/layout-best-practices.md- Layout patterns, context-agnostic views, and testabilityreferences/accessibility-patterns.md- Accessibility traits, grouping, Dynamic Type, and VoiceOverreferences/animation-basics.md- Core animation concepts, implicit/explicit animations, timing, performancereferences/animation-transitions.md- Transitions, custom transitions, Animatable protocolreferences/animation-advanced.md- Transactions, phase/keyframe animations (iOS 17+), completion handlers (iOS 17+)references/sheet-navigation-patterns.md- Sheet presentation and navigation patternsreferences/scroll-patterns.md- ScrollView patterns and programmatic scrollingreferences/image-optimization.md- AsyncImage, image downsampling, and optimizationreferences/liquid-glass.md- iOS 26+ Liquid Glass API
Philosophy
This skill focuses on facts and best practices, not architectural opinions:
- We don't enforce specific architectures (e.g., MVVM, VIPER)
- We do encourage separating business logic for testability
- We optimize for performance and maintainability
- We follow Apple's Human Interface Guidelines and API design patterns
Weekly Installs
81
Repository
sickn33/antigra…e-skillsGitHub Stars
21.4K
First Seen
Jan 31, 2026
Security Audits
Installed on
opencode79
gemini-cli78
codex78
github-copilot76
amp73
kimi-cli73