Accessibility
SwiftDS is built with accessibility as a core principle. Every component includes proper VoiceOver support, keyboard navigation, and follows WCAG 2.1 AA guidelines.
What We Support
VoiceOver
Full screen reader support on all platforms with descriptive labels and hints.
Dynamic Type
Text scales with user preferences up to 310% without breaking layouts.
Keyboard Navigation
Full keyboard support with logical focus order and visible indicators.
Color Contrast
WCAG AA compliant (4.5:1 for text, 3:1 for UI components).
Focus Management
Logical focus order with visible focus indicators throughout.
Semantic Traits
Proper accessibility traits (button, header, etc.) on all elements.
Accessibility Patterns
SwiftDS components follow consistent accessibility patterns. Here are the main patterns used throughout the system:
Interactive Components (Buttons, Links)
All interactive components provide clear labels, hints, and state information:
Button(action: action) {
// Button content
}
.accessibilityLabel(accessibilityLabel ?? title)
.accessibilityHint(isDisabled ? "Disabled" : "Double-tap to activate")
.accessibilityAddTraits(.isButton)Input Fields
Text inputs provide rich accessibility information with proper labels and error states:
TextField(placeholder, text: $text)
.accessibilityLabel(label ?? placeholder)
.accessibilityValue(text.isEmpty ? "Empty" : text)
.accessibilityHint(error != nil ? "Error: \(error!)" : "Text field")Display Components (Cards, Labels)
Display components combine multiple text elements into a single announcement:
VStack {
Text("Title")
Text("Subtitle")
}
.accessibilityElement(children: .combine)
.accessibilityLabel("Title, Subtitle")Progress Indicators
Progress components announce current state and percentage:
ProgressView(value: progress)
.accessibilityLabel("Loading")
.accessibilityValue("\(Int(progress * 100))%")Adjustable Components (Sliders, Ratings)
Components with adjustable values support swipe up/down gestures:
Slider(value: $value)
.accessibilityLabel("Volume")
.accessibilityValue("\(Int(value))%")
.accessibilityAdjustableAction { direction in
switch direction {
case .increment: value += 10
case .decrement: value -= 10
@unknown default: break
}
}Testing with VoiceOver
All SwiftDS components have been tested with VoiceOver on iOS and macOS. Here's how to test your implementation:
Enabling VoiceOver
iOS/iPadOS:
- Settings โ Accessibility โ VoiceOver โ On
- Or triple-click side button (if configured)
- Or ask Siri: "Turn on VoiceOver"
macOS:
- System Settings โ Accessibility โ VoiceOver โ On
- Or press Cmd+F5
- Or ask Siri: "Turn on VoiceOver"
VoiceOver Gestures (iOS)
Swipe rightNext elementSwipe leftPrevious elementDouble-tapActivate elementSwipe up/downAdjustable actionsTwo-finger swipe upRead from topTwo-finger swipe downRead from currentTesting Checklist
When testing a component with VoiceOver, verify these items:
Navigate to component - Can you reach it by swiping?
Hear label - Is the label descriptive and clear?
Hear hint - Does the hint explain how to interact?
Hear value - Is the current state/value announced?
Activate - Does double-tap trigger the action?
State changes - Are loading/disabled states announced?
Error states - Are errors clearly communicated?
Adjustable actions - Do swipe up/down work for sliders/ratings?
Focus order - Is the focus order logical?
No orphaned elements - Are all visible elements accessible?
Keyboard Navigation
SwiftUI provides automatic keyboard navigation for most components. Here are the supported shortcuts:
TabNext focusable elementShift+TabPrevious focusable elementSpaceActivate button/toggleReturnSubmit form/activate primary buttonEscapeDismiss modal/sheetArrow keysNavigate lists/gridsBest Practices
โ Do: Use Descriptive Labels
โ Bad
.accessibilityLabel("Button")โ Good
.accessibilityLabel("Sign in to your account")โ Do: Announce State Changes
โ Bad
Button("Submit") { submit() }โ Good
Button("Submit") { submit() }
.accessibilityHint(
isLoading ? "Loading" : "Double-tap to submit"
)โ Do: Hide Decorative Elements
โ Bad
HStack {
Image(systemName: "star.fill")
Text("Featured")
}โ Good
HStack {
Image(systemName: "star.fill")
.accessibilityHidden(true)
Text("Featured")
}โ Do: Group Related Content
โ Bad
VStack {
Text("John Doe")
Text("Software Engineer")
}โ Good
VStack {
Text("John Doe")
Text("Software Engineer")
}
.accessibilityElement(children: .combine)
.accessibilityLabel("John Doe, Software Engineer")Component Checklist
When creating new components, ensure they meet these accessibility requirements:
Required Features
accessibilityLabel - Descriptive label for screen readers
accessibilityHint - Usage hint (how to interact)
accessibilityValue - Current state/value (if applicable)
accessibilityElement - Proper grouping (combine/contain/ignore)
Traits - Correct semantic traits (button, header, etc.)
State changes - Loading/disabled/error states announced
Focus management - Logical focus order
Keyboard support - Tab navigation and shortcuts
Color contrast - WCAG AA compliant (4.5:1 for text)
Dynamic Type - Text scales properly
Resources
Accessibility is Built-In
When building with SwiftDS, accessibility is built-in by default. All 118+ components include proper VoiceOver support, keyboard navigation, and follow Apple's accessibility guidelines. No extra work required!