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