$npx -y skills add rshankras/claude-code-apple-skills --skill accessibility-generatorGenerate accessibility infrastructure for VoiceOver, Dynamic Type, and accessibility features. Use when improving app accessibility, adding accessibility labels and hints, or auditing compliance.
| 1 | # Accessibility Generator |
| 2 | |
| 3 | Generate accessibility infrastructure for VoiceOver, Dynamic Type, and accessibility features. |
| 4 | |
| 5 | ## When This Skill Activates |
| 6 | |
| 7 | - User wants to improve app accessibility |
| 8 | - User mentions VoiceOver, Dynamic Type, or accessibility |
| 9 | - User needs to add accessibility labels and hints |
| 10 | - User wants to audit accessibility compliance |
| 11 | |
| 12 | ## Pre-Generation Checks |
| 13 | |
| 14 | ```bash |
| 15 | # Check existing accessibility usage |
| 16 | grep -r "accessibilityLabel\|accessibilityHint\|AccessibilityFocused" --include="*.swift" | head -5 |
| 17 | ``` |
| 18 | |
| 19 | ## Key Features |
| 20 | |
| 21 | ### Accessibility Labels |
| 22 | |
| 23 | ```swift |
| 24 | Image(systemName: "heart.fill") |
| 25 | .accessibilityLabel("Favorite") |
| 26 | .accessibilityHint("Double tap to remove from favorites") |
| 27 | ``` |
| 28 | |
| 29 | ### Dynamic Type Support |
| 30 | |
| 31 | ```swift |
| 32 | Text("Title") |
| 33 | .font(.title) // Scales automatically |
| 34 | .dynamicTypeSize(...DynamicTypeSize.accessibility3) // Limit max size |
| 35 | ``` |
| 36 | |
| 37 | ### Reduce Motion |
| 38 | |
| 39 | ```swift |
| 40 | @Environment(\.accessibilityReduceMotion) private var reduceMotion |
| 41 | |
| 42 | withAnimation(reduceMotion ? nil : .spring()) { |
| 43 | // Animation |
| 44 | } |
| 45 | ``` |
| 46 | |
| 47 | ### VoiceOver Groups |
| 48 | |
| 49 | ```swift |
| 50 | VStack { |
| 51 | Text("Item Name") |
| 52 | Text("$9.99") |
| 53 | } |
| 54 | .accessibilityElement(children: .combine) |
| 55 | ``` |
| 56 | |
| 57 | ## Visual Accessibility: Numbers and APIs (WWDC20) |
| 58 | |
| 59 | | Setting | Threshold / API | What to do | |
| 60 | |---------|-----------------|------------| |
| 61 | | Contrast | **4.5:1 minimum** ("generally the lowest acceptable ratio"); ~**7.5:1** for comfort on dark backgrounds | Check text and glyphs against their actual backgrounds | |
| 62 | | Differentiate Without Color | `UIAccessibility.shouldDifferentiateWithoutColor` | Add shapes/symbols wherever color is the only signal (red/green states) | |
| 63 | | Button Shapes | `UIAccessibility.buttonShapesEnabled` + its change notification | Show borders/underlines on plain-text buttons when on | |
| 64 | | Increase Contrast | System colors adapt for free; custom colors need a **"High Contrast" variant in the asset catalog** | Never ship a single hex for both modes | |
| 65 | | Dynamic Type | `preferredContentSizeCategory` | **Never truncate** — set line count to 0 so text wraps; reflow layout at accessibility sizes | |
| 66 | | Bold Text | `UIAccessibility.isBoldTextEnabled` | Free with system text styles; custom fonts must swap weights manually | |
| 67 | | Reduce Motion | `isReduceMotionEnabled`, `prefersCrossFadeTransitions` | Gate animations, parallax, and video autoplay; prefer cross-fades over sliding transitions | |
| 68 | | Smart Invert | `.accessibilityIgnoresInvertColors()` | Apply to photos, videos, and full-color icons so they don't invert | |
| 69 | | Reduce Transparency | `UIAccessibility.isReduceTransparencyEnabled` | Render blur/vibrancy backgrounds as opaque | |
| 70 | |
| 71 | SwiftUI mirrors most of these as environment values (`\.accessibilityReduceMotion` above, plus `\.accessibilityDifferentiateWithoutColor`, `\.legibilityWeight`, `\.accessibilityReduceTransparency`). |
| 72 | |
| 73 | ## Deep Patterns (accessibility-patterns.md) |
| 74 | |
| 75 | The full recipes live in [accessibility-patterns.md](accessibility-patterns.md): |
| 76 | |
| 77 | - Label-writing rules — context ladder, no control types, succinctness, localize (WWDC19 254) |
| 78 | - Custom actions doctrine — clutter/speed rationale, hide replaced buttons, widget intents (WWDC19 250, WWDC24 10073) |
| 79 | - Custom rotors, UIKit and SwiftUI (WWDC20 10116, WWDC21 10119) |
| 80 | - Data-rich rows via the More Content rotor / `AXCustomContent` (WWDC21 10121) |
| 81 | - Announcements with priorities, `.isToggle`, zoom, direct touch, block-based setters (WWDC23 10036) |
| 82 | - Custom-control technique selection: adjustable vs passthrough vs custom actions vs direct touch (WWDC26 220) |
| 83 | - Switch Control grouping and timeout rules (WWDC20 10019); Full Keyboard Access (WWDC21 10120) |
| 84 | - Reading-app text navigation, page turns, `UITextInput` adoption (WWDC26 219) |
| 85 | |
| 86 | ## Inclusive Design Principles (WWDC25) |
| 87 | |
| 88 | - **About 1 in 7 people has a disability** — accessibility features are mainstream features. |
| 89 | - Provide information through **multiple senses**: captions for audio, audible/haptic paths for visual cues. |
| 90 | - Support **multiple input methods** — touch, keyboard, voice, switch — for every action. |
| 91 | - **Larger Text scales text up to ~3x** — layouts must reflow, not clip or overlap. |
| 92 | - Inclusion is **iterative, not one-time** — re-audit each release, not just before launch. |
| 93 | |
| 94 | ## Generated Files |
| 95 | |
| 96 | ``` |
| 97 | Sources/Accessibility/ |
| 98 | ├── AccessibilityModifiers.swift # Custom view modifiers |
| 99 | ├── AccessibilityHelpers.swift # Label builders |
| 100 | └── AccessibilityStrings.swift # Localized labels |
| 101 | ``` |
| 102 | |
| 103 | ## Audit Checklist |
| 104 | |
| 105 | - [ ] All interactive elements have labels |
| 106 | - [ ] Images have descriptions or are hidden decoratively |
| 107 | - [ ] Color is not the only indicator |
| 108 | - [ ] Touch targets are at least 44 |