SwiftUI UI/UX Review Skill
Comprehensive review and analysis of SwiftUI interfaces for iOS 17/18/26+ with focus on animations, Liquid Glass design language, Apple Human Interface Guidelines (HIG), accessibility standards, and modern UI/UX patterns.
When to Use This Skill
- Reviewing animations - springs, keyframes, transitions, micro-interactions, liquid glass morphing
- Reviewing SwiftUI code for UI/UX best practices
- Auditing compliance with iOS 26 Liquid Glass design language
- Checking accessibility implementation (VoiceOver, Dynamic Type, Reduce Motion)
- Analyzing navigation, onboarding, tabs, sheets, and modal patterns
- Identifying common UI/UX mistakes and anti-patterns
- Evaluating animation performance and timing
- Providing actionable recommendations for interface improvements
Review Process
Step 1: Gather Context
Before reviewing, collect information about:
- Target iOS version - iOS 17+ for PhaseAnimator/KeyframeAnimator; iOS 26+ for Liquid Glass
- App purpose - Different apps require different animation intensities
- User demographics - Accessibility requirements vary by audience
- Existing design system - Check for design tokens and theming
Step 2: Structural Analysis
Analyze the SwiftUI code structure for:
| Component |
Check For |
| Navigation |
NavigationStack usage, tab bar implementation, deep linking support |
| State Management |
@State, @Binding, @Observable patterns, data flow |
| View Hierarchy |
Proper component decomposition, reusability |
| Modifiers |
Correct modifier ordering, accessibility modifiers |
| Animations |
Spring parameters, timing, transitions, accessibility compliance |
Step 3: Animation Review (NEW)
Animation Quality Checklist
| Aspect |
Standard |
Check For |
| Timing |
100-500ms |
Animations not too fast or slow |
| Springs |
Used for interactive |
response, dampingFraction appropriate |
| Purpose |
Communicates change |
Not gratuitous or distracting |
| Performance |
No frame drops |
drawingGroup() for complex views |
| Accessibility |
Respects settings |
Checks accessibilityReduceMotion |
Spring Animation Standards
Recommended Springs:
// Button press - quick, bouncy
.spring(response: 0.3, dampingFraction: 0.6)
// Modal presentation - smooth, natural
.spring(response: 0.5, dampingFraction: 0.8)
// Card expansion - elegant, controlled
.spring(response: 0.6, dampingFraction: 0.85)
// Subtle hover - minimal, fast
.spring(response: 0.2, dampingFraction: 0.9)
iOS 17+ Presets:
.bouncy - High bounce, playful
.smooth - No overshoot, professional
.snappy - Quick response
iOS 26+ New APIs (WWDC 2025):
@Animatable macro - Auto-synthesizes Animatable conformance for Shapes
@AnimatableIgnored macro - Excludes properties from animation interpolation
.symbolEffect(.drawOn) / .symbolEffect(.drawOff) - SF Symbols 7 stroke-based reveal/dismiss animations (supports .wholeSymbol, .byLayer, .individually)
.backgroundExtensionEffect() - Blur extension beyond view bounds (for sidebars, inspectors)
tabViewBottomAccessory { } - Persistent control above tab bar (gets glass capsule automatically)
ToolbarSpacer - Control spacing between toolbar items
scrollExtensionMode(.underSidebar) - Extend scroll content under sidebar
- Sheet morphing:
matchedTransitionSource(id:in:) + navigationTransition(.zoom(sourceID:in:))
- Rich
TextEditor with AttributedString binding and onSelectionChange
- Label spacing:
.labelIconToTitleSpacing, .labelReservedIconWidth
Common Animation Issues
| Issue |
Severity |
Solution |
.animation() without value |
High |
Use .animation(_:value:) |
| Linear timing for UI |
Medium |
Use springs for natural feel |
No reduceMotion check |
High |
Add @Environment(\.accessibilityReduceMotion) |
| Heavy views in keyframes |
High |
Use drawingGroup() |
Multiple conflicting withAnimation |
Medium |
Consolidate into single block |
| Animation during scroll |
Medium |
Defer until scroll ends |
Transition Review
Check transitions use:
.asymmetric(insertion:removal:) for directional animations
.combined(with:) for multi-property transitions
- Appropriate timing that matches gesture direction
Micro-Interactions
Verify:
- Button press has visual feedback (scale, opacity)
- Haptic feedback matches action type (
.success, .error, .selection)
- Feedback not excessive or annoying
Step 4: Liquid Glass Compliance (iOS 26+)
Glass Variants (IMPORTANT — only 3 exist):
| Variant |
Use Case |
.regular |
Standard navigation elements, toolbars, tabs |
.clear |
Subtle controls over media-rich backgrounds |
.identity |
No effect — for conditional toggling / accessibility |
WARNING: .prominent is NOT a glass variant. Use .buttonStyle(.glassProminent) for prominent buttons.
Appropriate Uses:
- Navigation bars and toolbars
- Tab bars and bottom accessories (use
tabViewBottomAccessory for floating bars)
- Floating action buttons
- Sheets, popovers, and menus (system applies glass automatically in iOS 26)
- Context-sensitive controls
ToolbarSpacer for grouping toolbar items
Avoid Liquid Glass For:
- Content layer (lists, tables, media)
- Full-screen backgrounds
- Scrollable content
- Stacked glass layers (glass cannot sample other glass)
- Custom shadows/borders (trust system edge effects)
Glass Morphing Animations:
- Use
GlassEffectContainer for coordinated morphing
- Apply
glassEffectID(_:in:) for morph coordination
- Use
glassEffectUnion(id:namespace:) to merge related controls into one glass shape
- Use
.bouncy animation for glass transitions
- Wrap state changes in
withAnimation(.bouncy)
- Don't use
presentationBackground() on sheets — system handles it
New iOS 26 Layout APIs:
tabViewBottomAccessory { } — persistent control above tab bar (like Now Playing)
ToolbarSpacer — control spacing between toolbar items
scrollExtensionMode(.underSidebar) — extend scroll content under sidebar
backgroundExtensionEffect() — extend/blur content behind sidebars
- Sheet morphing:
matchedTransitionSource(id:in:) + navigationTransition(.zoom(sourceID:in:))
Check for proper .glassEffect() usage with #available(iOS 26.0, *) guards.
Step 5: Pattern Validation
Onboarding Patterns
- iOS 18+: Prefer ScrollView with
scrollTargetBehavior(.viewAligned) over TabView
- Use
@AppStorage for tracking completion state
- Present using
.fullScreenCover for immersive experience
- Include skip option and progress indicators
- Animations: Staggered entry with
.delay(), parallax effects
Tab Navigation
- Each tab maintains its own NavigationStack
- State preserved when switching tabs
- Coordinator pattern for complex flows
- iOS 26: Tabs auto-shrink on scroll
- Animations:
matchedGeometryEffect for tab indicator
Sheets and Modals
- Attach
.sheet to outermost container view
- Use
presentationDetents for height control (iOS 16+)
interactiveDismissDisabled() when dismissal must be controlled
- Forms for settings/profiles, fullScreenCover for immersive content
- Animations: Spring presentation with
response: 0.5, dampingFraction: 0.8
Loading States
- Use
.redacted(reason: .placeholder) for skeleton views
- Model states with enum (loading, loaded, empty, error)
- ContentUnavailableView for empty states (iOS 17+)
.unredacted() for fixed elements during loading
- Animations: Shimmer effect with repeating linear gradient
Counter/Numeric Displays
- Use
.contentTransition(.numericText()) for animated counters
- Combine with
.sensoryFeedback(.increase, trigger:) for haptics
Permission Request Patterns (App Store Guideline 5.1.1)
Critical: Permission primers (custom alerts before iOS permission dialogs) must NOT have exit/dismiss buttons.
Compliant Pattern:
// OK: Primer with only "Continue" - user must proceed to iOS dialog
.alert("Camera Access", isPresented: $showPrimer) {
Button("Continue") { requestCameraPermission() }
} message: {
Text("We need camera access to scan documents.")
}
Non-Compliant Pattern (App Store Rejection):
// REJECTED: "Not Now" lets user skip the iOS permission dialog
.alert("Camera Access", isPresented: $showPrimer) {
Button("Continue") { requestCameraPermission() }
Button("Not Now", role: .cancel) { dismiss() } // ← VIOLATION
} message: {
Text("We need camera access to scan documents.")
}
Best Practices:
- If showing a primer, user MUST proceed to the actual iOS permission dialog
- No "Skip", "Not Now", "Later", or "Cancel" buttons on pre-permission primers
- After denial, you CAN show an alert with "Open Settings" + "Cancel"
- Consider skipping primers entirely - iOS dialogs show your Info.plist usage descriptions
- Request permissions contextually (when user tries to use the feature), not on app launch
Applies to: Camera, Microphone, Photos, Location, Contacts, Calendars, Speech Recognition, Health, Motion, Bluetooth, Local Network, Tracking (ATT)
Step 6: Accessibility Audit
Required Checks:
| Modifier |
Purpose |
.accessibilityLabel() |
Descriptive label for VoiceOver |
.accessibilityHint() |
Action context for users |
.accessibilityElement(children:) |
Group related elements |
.accessibilityHidden() |
Hide decorative elements |
Dynamic Type: Verify text scales with system settings. Avoid fixed font sizes.
Reduce Transparency: Check @Environment(\.accessibilityReduceTransparency) for Liquid Glass fallbacks.
Reduce Motion: Check @Environment(\.accessibilityReduceMotion) and disable/simplify animations.
Color Contrast: Use .primary, .secondary over hardcoded colors.
Step 7: Generate Report
Structure findings as:
## UI/UX Review Summary
### Strengths
- [List positive patterns found]
### Animation Issues
1. **[Issue Name]** - Severity: High/Medium/Low
- Location: `FileName.swift:LineNumber`
- Problem: [Description]
- Recommendation: [Specific fix with code]
### UI/UX Issues
1. **[Issue Name]** - Severity: High/Medium/Low
- Location: `FileName.swift:LineNumber`
- Problem: [Description]
- Recommendation: [Specific fix]
### Recommendations
- [Prioritized list of improvements]
### Code Examples
- [Before/after code snippets]
Quick Reference: Common Issues
| Issue |
Severity |
Solution |
| Permission primer with exit button |
Critical |
Remove "Not Now"/"Skip" - user must proceed to iOS dialog (Guideline 5.1.1) |
| Liquid Glass on content layer |
High |
Move to navigation layer only |
| Missing accessibility labels |
High |
Add .accessibilityLabel() to interactive elements |
No reduceMotion check |
High |
Add environment check, simplify animations |
.animation() without value |
High |
Use .animation(_:value:) |
| Fixed font sizes |
Medium |
Use system semantic fonts |
| Stacked glass layers |
Medium |
Reduce glass layers, add spacing |
| Linear animation for buttons |
Medium |
Use spring with dampingFraction: 0.6-0.8 |
| No haptic feedback |
Low |
Add .sensoryFeedback() for important actions |
| TabView for iOS 18+ onboarding |
Low |
Migrate to ScrollView pattern |
| Sheet attached to button |
Low |
Move to container view |
Animation API Quick Reference
iOS 17+ Animators
// PhaseAnimator - Multi-step cycling
PhaseAnimator([Phase.a, .b, .c], trigger: value) { phase in
Content().modifier(for: phase)
} animation: { phase in
.spring(response: 0.3)
}
// KeyframeAnimator - Fine-grained control
.keyframeAnimator(initialValue: Values(), trigger: trigger) { content, value in
content.scaleEffect(value.scale)
} keyframes: { _ in
KeyframeTrack(\.scale) {
SpringKeyframe(1.2, duration: 0.2)
SpringKeyframe(1.0, duration: 0.3)
}
}
Transitions
// Combined transition
.transition(.move(edge: .bottom).combined(with: .opacity))
// Asymmetric
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .move(edge: .leading)
))
// iOS 17+
.transition(.blurReplace)
.transition(.push(from: .bottom))
Haptic Feedback (iOS 17+)
.sensoryFeedback(.success, trigger: value)
.sensoryFeedback(.selection, trigger: selection)
.sensoryFeedback(.impact, trigger: collision)
Design Tokens Reference
Recommended spacing scale:
xs: 4pt, sm: 8pt, md: 16pt, lg: 24pt, xl: 32pt
Use semantic colors:
.primary, .secondary for text
.background, .secondaryBackground for surfaces
- System tints for interactive elements
Additional Resources
Reference Files
For detailed patterns and guidelines, consult:
references/animation-guide.md - Comprehensive animation reference with springs, keyframes, transitions, micro-interactions, and performance optimization
references/liquid-glass-guide.md - Complete iOS 26 Liquid Glass implementation guide with code examples
references/ui-patterns.md - Detailed SwiftUI patterns for navigation, onboarding, forms, loading states
references/accessibility-checklist.md - Complete VoiceOver, Dynamic Type, Reduce Motion audit checklist with testing procedures
External Resources
Apple Official:
Animation Libraries:
Hero Transitions:
Liquid Glass & iOS 26:
Tutorials:
1---2name: swiftui-ui-ux-review3description: This skill should be used when the user asks to "review SwiftUI UI", "analyze iOS interface", "check UI/UX patterns", "review liquid glass implementation", "audit SwiftUI accessibility", "check iOS 26 design compliance", "review onboarding flow", "analyze navigation patterns", "review animations", "check animation performance", "audit motion design", "review transitions", "analyze micro-interactions", or mentions SwiftUI design review, UI audit, UX analysis, iOS 26 liquid glass, HIG compliance, accessibility review, animation review, spring animations, keyframe animations, PhaseAnimator, matchedGeometryEffect, haptic feedback, motion design, @Animatable macro, SF Symbols animation, GlassEffectContainer, or symbolEffect for iOS apps.4---56# SwiftUI UI/UX Review Skill78Comprehensive review and analysis of SwiftUI interfaces for iOS 17/18/26+ with focus on **animations**, Liquid Glass design language, Apple Human Interface Guidelines (HIG), accessibility standards, and modern UI/UX patterns.910## When to Use This Skill1112- **Reviewing animations** - springs, keyframes, transitions, micro-interactions, liquid glass morphing13- Reviewing SwiftUI code for UI/UX best practices14- Auditing compliance with iOS 26 Liquid Glass design language15- Checking accessibility implementation (VoiceOver, Dynamic Type, Reduce Motion)16- Analyzing navigation, onboarding, tabs, sheets, and modal patterns17- Identifying common UI/UX mistakes and anti-patterns18- Evaluating animation performance and timing19- Providing actionable recommendations for interface improvements2021## Review Process2223### Step 1: Gather Context2425Before reviewing, collect information about:261. **Target iOS version** - iOS 17+ for PhaseAnimator/KeyframeAnimator; iOS 26+ for Liquid Glass272. **App purpose** - Different apps require different animation intensities283. **User demographics** - Accessibility requirements vary by audience294. **Existing design system** - Check for design tokens and theming3031### Step 2: Structural Analysis3233Analyze the SwiftUI code structure for:3435| Component | Check For |36|-----------|-----------|37| Navigation | NavigationStack usage, tab bar implementation, deep linking support |38| State Management | @State, @Binding, @Observable patterns, data flow |39| View Hierarchy | Proper component decomposition, reusability |40| Modifiers | Correct modifier ordering, accessibility modifiers |41| **Animations** | Spring parameters, timing, transitions, accessibility compliance |4243### Step 3: Animation Review (NEW)4445#### Animation Quality Checklist4647| Aspect | Standard | Check For |48|--------|----------|-----------|49| **Timing** | 100-500ms | Animations not too fast or slow |50| **Springs** | Used for interactive | `response`, `dampingFraction` appropriate |51| **Purpose** | Communicates change | Not gratuitous or distracting |52| **Performance** | No frame drops | `drawingGroup()` for complex views |53| **Accessibility** | Respects settings | Checks `accessibilityReduceMotion` |5455#### Spring Animation Standards5657**Recommended Springs:**58```swift59// Button press - quick, bouncy60.spring(response: 0.3, dampingFraction: 0.6)6162// Modal presentation - smooth, natural63.spring(response: 0.5, dampingFraction: 0.8)6465// Card expansion - elegant, controlled66.spring(response: 0.6, dampingFraction: 0.85)6768// Subtle hover - minimal, fast69.spring(response: 0.2, dampingFraction: 0.9)70```7172**iOS 17+ Presets:**73- `.bouncy` - High bounce, playful74- `.smooth` - No overshoot, professional75- `.snappy` - Quick response7677**iOS 26+ New APIs (WWDC 2025):**78- `@Animatable` macro - Auto-synthesizes `Animatable` conformance for Shapes79- `@AnimatableIgnored` macro - Excludes properties from animation interpolation80- `.symbolEffect(.drawOn)` / `.symbolEffect(.drawOff)` - SF Symbols 7 stroke-based reveal/dismiss animations (supports `.wholeSymbol`, `.byLayer`, `.individually`)81- `.backgroundExtensionEffect()` - Blur extension beyond view bounds (for sidebars, inspectors)82- `tabViewBottomAccessory { }` - Persistent control above tab bar (gets glass capsule automatically)83- `ToolbarSpacer` - Control spacing between toolbar items84- `scrollExtensionMode(.underSidebar)` - Extend scroll content under sidebar85- Sheet morphing: `matchedTransitionSource(id:in:)` + `navigationTransition(.zoom(sourceID:in:))`86- Rich `TextEditor` with `AttributedString` binding and `onSelectionChange`87- Label spacing: `.labelIconToTitleSpacing`, `.labelReservedIconWidth`8889#### Common Animation Issues9091| Issue | Severity | Solution |92|-------|----------|----------|93| `.animation()` without value | High | Use `.animation(_:value:)` |94| Linear timing for UI | Medium | Use springs for natural feel |95| No `reduceMotion` check | High | Add `@Environment(\.accessibilityReduceMotion)` |96| Heavy views in keyframes | High | Use `drawingGroup()` |97| Multiple conflicting `withAnimation` | Medium | Consolidate into single block |98| Animation during scroll | Medium | Defer until scroll ends |99100#### Transition Review101102**Check transitions use:**103- `.asymmetric(insertion:removal:)` for directional animations104- `.combined(with:)` for multi-property transitions105- Appropriate timing that matches gesture direction106107#### Micro-Interactions108109**Verify:**110- Button press has visual feedback (scale, opacity)111- Haptic feedback matches action type (`.success`, `.error`, `.selection`)112- Feedback not excessive or annoying113114### Step 4: Liquid Glass Compliance (iOS 26+)115116**Glass Variants (IMPORTANT — only 3 exist):**117118| Variant | Use Case |119|---------|----------|120| `.regular` | Standard navigation elements, toolbars, tabs |121| `.clear` | Subtle controls over media-rich backgrounds |122| `.identity` | No effect — for conditional toggling / accessibility |123124**WARNING:** `.prominent` is NOT a glass variant. Use `.buttonStyle(.glassProminent)` for prominent buttons.125126**Appropriate Uses:**127- Navigation bars and toolbars128- Tab bars and bottom accessories (use `tabViewBottomAccessory` for floating bars)129- Floating action buttons130- Sheets, popovers, and menus (system applies glass automatically in iOS 26)131- Context-sensitive controls132- `ToolbarSpacer` for grouping toolbar items133134**Avoid Liquid Glass For:**135- Content layer (lists, tables, media)136- Full-screen backgrounds137- Scrollable content138- Stacked glass layers (glass cannot sample other glass)139- Custom shadows/borders (trust system edge effects)140141**Glass Morphing Animations:**142- Use `GlassEffectContainer` for coordinated morphing143- Apply `glassEffectID(_:in:)` for morph coordination144- Use `glassEffectUnion(id:namespace:)` to merge related controls into one glass shape145- Use `.bouncy` animation for glass transitions146- Wrap state changes in `withAnimation(.bouncy)`147- Don't use `presentationBackground()` on sheets — system handles it148149**New iOS 26 Layout APIs:**150- `tabViewBottomAccessory { }` — persistent control above tab bar (like Now Playing)151- `ToolbarSpacer` — control spacing between toolbar items152- `scrollExtensionMode(.underSidebar)` — extend scroll content under sidebar153- `backgroundExtensionEffect()` — extend/blur content behind sidebars154- Sheet morphing: `matchedTransitionSource(id:in:)` + `navigationTransition(.zoom(sourceID:in:))`155156Check for proper `.glassEffect()` usage with `#available(iOS 26.0, *)` guards.157158### Step 5: Pattern Validation159160#### Onboarding Patterns161- **iOS 18+**: Prefer ScrollView with `scrollTargetBehavior(.viewAligned)` over TabView162- Use `@AppStorage` for tracking completion state163- Present using `.fullScreenCover` for immersive experience164- Include skip option and progress indicators165- **Animations**: Staggered entry with `.delay()`, parallax effects166167#### Tab Navigation168- Each tab maintains its own NavigationStack169- State preserved when switching tabs170- Coordinator pattern for complex flows171- iOS 26: Tabs auto-shrink on scroll172- **Animations**: `matchedGeometryEffect` for tab indicator173174#### Sheets and Modals175- Attach `.sheet` to outermost container view176- Use `presentationDetents` for height control (iOS 16+)177- `interactiveDismissDisabled()` when dismissal must be controlled178- Forms for settings/profiles, fullScreenCover for immersive content179- **Animations**: Spring presentation with `response: 0.5, dampingFraction: 0.8`180181#### Loading States182- Use `.redacted(reason: .placeholder)` for skeleton views183- Model states with enum (loading, loaded, empty, error)184- ContentUnavailableView for empty states (iOS 17+)185- `.unredacted()` for fixed elements during loading186- **Animations**: Shimmer effect with repeating linear gradient187188#### Counter/Numeric Displays189- Use `.contentTransition(.numericText())` for animated counters190- Combine with `.sensoryFeedback(.increase, trigger:)` for haptics191192#### Permission Request Patterns (App Store Guideline 5.1.1)193194**Critical:** Permission primers (custom alerts before iOS permission dialogs) must NOT have exit/dismiss buttons.195196**Compliant Pattern:**197```swift198// OK: Primer with only "Continue" - user must proceed to iOS dialog199.alert("Camera Access", isPresented: $showPrimer) {200 Button("Continue") { requestCameraPermission() }201} message: {202 Text("We need camera access to scan documents.")203}204```205206**Non-Compliant Pattern (App Store Rejection):**207```swift208// REJECTED: "Not Now" lets user skip the iOS permission dialog209.alert("Camera Access", isPresented: $showPrimer) {210 Button("Continue") { requestCameraPermission() }211 Button("Not Now", role: .cancel) { dismiss() } // ← VIOLATION212} message: {213 Text("We need camera access to scan documents.")214}215```216217**Best Practices:**218- If showing a primer, user MUST proceed to the actual iOS permission dialog219- No "Skip", "Not Now", "Later", or "Cancel" buttons on pre-permission primers220- After denial, you CAN show an alert with "Open Settings" + "Cancel"221- Consider skipping primers entirely - iOS dialogs show your Info.plist usage descriptions222- Request permissions contextually (when user tries to use the feature), not on app launch223224**Applies to:** Camera, Microphone, Photos, Location, Contacts, Calendars, Speech Recognition, Health, Motion, Bluetooth, Local Network, Tracking (ATT)225226### Step 6: Accessibility Audit227228**Required Checks:**229230| Modifier | Purpose |231|----------|---------|232| `.accessibilityLabel()` | Descriptive label for VoiceOver |233| `.accessibilityHint()` | Action context for users |234| `.accessibilityElement(children:)` | Group related elements |235| `.accessibilityHidden()` | Hide decorative elements |236237**Dynamic Type:** Verify text scales with system settings. Avoid fixed font sizes.238239**Reduce Transparency:** Check `@Environment(\.accessibilityReduceTransparency)` for Liquid Glass fallbacks.240241**Reduce Motion:** Check `@Environment(\.accessibilityReduceMotion)` and disable/simplify animations.242243**Color Contrast:** Use `.primary`, `.secondary` over hardcoded colors.244245### Step 7: Generate Report246247Structure findings as:248249```markdown250## UI/UX Review Summary251252### Strengths253- [List positive patterns found]254255### Animation Issues2561. **[Issue Name]** - Severity: High/Medium/Low257 - Location: `FileName.swift:LineNumber`258 - Problem: [Description]259 - Recommendation: [Specific fix with code]260261### UI/UX Issues2621. **[Issue Name]** - Severity: High/Medium/Low263 - Location: `FileName.swift:LineNumber`264 - Problem: [Description]265 - Recommendation: [Specific fix]266267### Recommendations268- [Prioritized list of improvements]269270### Code Examples271- [Before/after code snippets]272```273274## Quick Reference: Common Issues275276| Issue | Severity | Solution |277|-------|----------|----------|278| Permission primer with exit button | **Critical** | Remove "Not Now"/"Skip" - user must proceed to iOS dialog (Guideline 5.1.1) |279| Liquid Glass on content layer | High | Move to navigation layer only |280| Missing accessibility labels | High | Add `.accessibilityLabel()` to interactive elements |281| No `reduceMotion` check | High | Add environment check, simplify animations |282| `.animation()` without value | High | Use `.animation(_:value:)` |283| Fixed font sizes | Medium | Use system semantic fonts |284| Stacked glass layers | Medium | Reduce glass layers, add spacing |285| Linear animation for buttons | Medium | Use spring with `dampingFraction: 0.6-0.8` |286| No haptic feedback | Low | Add `.sensoryFeedback()` for important actions |287| TabView for iOS 18+ onboarding | Low | Migrate to ScrollView pattern |288| Sheet attached to button | Low | Move to container view |289290## Animation API Quick Reference291292### iOS 17+ Animators293294```swift295// PhaseAnimator - Multi-step cycling296PhaseAnimator([Phase.a, .b, .c], trigger: value) { phase in297 Content().modifier(for: phase)298} animation: { phase in299 .spring(response: 0.3)300}301302// KeyframeAnimator - Fine-grained control303.keyframeAnimator(initialValue: Values(), trigger: trigger) { content, value in304 content.scaleEffect(value.scale)305} keyframes: { _ in306 KeyframeTrack(\.scale) {307 SpringKeyframe(1.2, duration: 0.2)308 SpringKeyframe(1.0, duration: 0.3)309 }310}311```312313### Transitions314315```swift316// Combined transition317.transition(.move(edge: .bottom).combined(with: .opacity))318319// Asymmetric320.transition(.asymmetric(321 insertion: .move(edge: .trailing),322 removal: .move(edge: .leading)323))324325// iOS 17+326.transition(.blurReplace)327.transition(.push(from: .bottom))328```329330### Haptic Feedback (iOS 17+)331332```swift333.sensoryFeedback(.success, trigger: value)334.sensoryFeedback(.selection, trigger: selection)335.sensoryFeedback(.impact, trigger: collision)336```337338## Design Tokens Reference339340Recommended spacing scale:341- `xs`: 4pt, `sm`: 8pt, `md`: 16pt, `lg`: 24pt, `xl`: 32pt342343Use semantic colors:344- `.primary`, `.secondary` for text345- `.background`, `.secondaryBackground` for surfaces346- System tints for interactive elements347348## Additional Resources349350### Reference Files351352For detailed patterns and guidelines, consult:353- **`references/animation-guide.md`** - Comprehensive animation reference with springs, keyframes, transitions, micro-interactions, and performance optimization354- **`references/liquid-glass-guide.md`** - Complete iOS 26 Liquid Glass implementation guide with code examples355- **`references/ui-patterns.md`** - Detailed SwiftUI patterns for navigation, onboarding, forms, loading states356- **`references/accessibility-checklist.md`** - Complete VoiceOver, Dynamic Type, Reduce Motion audit checklist with testing procedures357358### External Resources359360**Apple Official:**361- [Human Interface Guidelines - Motion](https://developer.apple.com/design/human-interface-guidelines/motion)362- [Animating views and transitions](https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions)363- [Applying Liquid Glass to custom views](https://developer.apple.com/documentation/SwiftUI/Applying-Liquid-Glass-to-custom-views)364- [WWDC23: Demystify SwiftUI performance](https://developer.apple.com/videos/play/wwdc2023/10160/)365- [WWDC18: Designing Fluid Interfaces](https://developer.apple.com/videos/play/wwdc2018/803/)366- [WWDC25: Meet Liquid Glass](https://developer.apple.com/videos/play/wwdc2025/219/)367368**Animation Libraries:**369- [Pow](https://github.com/EmergeTools/Pow) - Delightful SwiftUI effects (Spray, Shake, Shine, Jump, Rise, Spin)370- [AnimatedTabBar](https://github.com/exyte/AnimatedTabBar) - Preset tab bar animations371- [open-swiftui-animations](https://github.com/amosgyamfi/open-swiftui-animations) - Loading, looping, spring examples372- [Hero](https://github.com/HeroTransitions/Hero) - Elegant transition library373- [FlowStack](https://github.com/velos/FlowStack) - Hero animations with NavigationStack API374- [SkeletonUI](https://github.com/CSolanaM/SkeletonUI) - Elegant skeleton loading375376**Hero Transitions:**377- [swiftui-hero-animations](https://github.com/swiftui-lab/swiftui-hero-animations) - matchedGeometryEffect examples378- [swiftui-hero-animations-no-transitions](https://github.com/swiftui-lab/swiftui-hero-animations-no-transitions) - Morphing without transitions379380**Liquid Glass & iOS 26:**381- [iOS-26-by-Examples](https://github.com/artemnovichkov/iOS-26-by-Examples) - Comprehensive iOS 26 feature examples382- [LiquidGlassReference](https://github.com/conorluddy/LiquidGlassReference) - Ultimate Swift/SwiftUI reference383- [LiquidGlassSwiftUI](https://github.com/mertozseven/LiquidGlassSwiftUI) - Sample Liquid Glass app384385**Tutorials:**386- [SwiftUI Lab - PhaseAnimator](https://swiftui-lab.com/swiftui-animations-part7/)387- [AppCoda - KeyframeAnimator](https://www.appcoda.com/keyframeanimator/)388- [Hacking with Swift - Spring Animations](https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-a-spring-animation)389- [Design+Code - Phase Animator](https://designcode.io/swiftui-handbook-phase-animator/)390- [Jacob's Tech Tavern - Keyframe Animations](https://blog.jacobstechtavern.com/p/swiftui-keyframe-animations)