Managing Content Visibility & Hierarchy
In iOS, managing content visibility and hierarchy is key to creating user interfaces that everyone can navigate with ease. By hiding purely decorative elements from assistive technologies like VoiceOver, you avoid cluttering the reading order. And by grouping related items, you provide logical, coherent announcements.
🎯 Why It Matters
Users with visual impairments often increase their system font size to improve readability. Your app should respect these preferences and scale text appropriately without breaking your layout.
💻 Implementation
Incorrect code example: Exposing Non-Essential Images
Demo Description
This SwiftUI snippet presents several accessibility concerns: VoiceOver unnecessarily interprets the circle and checkmark icons as images. Furthermore, it does not indicate whether an answer has been selected, leaving users without clear feedback on their choice.
Implementation
// SwiftUI
// INACCESSIBLE: Non-essential circle image is read aloud,
// and selection status isn't conveyed to VoiceOver.
struct AnswerRowView: View {
let answerText: String
let isSelected: Bool
var body: some View {
HStack(spacing: 8) {
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.foregroundColor(isSelected ? .blue : .gray)
Text(answerText)
.foregroundColor(.primary)
Spacer()
}
.padding()
.background(Color(UIColor.secondarySystemBackground))
.cornerRadius(8)
// No accessibility modifiers, so elements are not grouped
// and selection is not announced by VoiceOver.
}
}
Code Explanation
We now apply the accessibility-Hidden function parsing the value of true, to the images so that VoiceOver ignores them and then we wrap everything in the accessibility-Element function with the parameter children-colon dot-ignore, while setting a custom accessibility-label, using the accessibility-label function for the text and the accessibility-Value function for the selection state. Consequently, VoiceOver perceives a single element that reads “Answer-Text. Selected” or “Answer-Text. Not selected.”
Correct code example: Accessible Answer Row
Demo Description
This SwiftUI snippet presents several accessibility concerns: VoiceOver unnecessarily interprets the circle and checkmark icons as images. Furthermore, it does not indicate whether an answer has been selected, leaving users without clear feedback on their choice.
Implementation
// SwiftUI
// ACCESSIBLE: Hides decorative icons, groups children into a single element, and announces selection.
struct AnswerRowView: View {
let answerText: String
let isSelected: Bool
var body: some View {
HStack {
// Decorative icon hidden from VoiceOver
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.accessibilityHidden(true)
Text(answerText)
}
.accessibilityElement(children: .ignore)
.accessibilityLabel(answerText)
.accessibilityValue(isSelected ? "Selected" : "Not selected")
}
}
Code Explanation
In this snippet, setting the accessibility-Element function with the parameter children-colon dot-combine merges the Text elements into a single announcement, and the custom accessibility-Label, using the accessibility-Label function, ensures that VoiceOver reads both the question number and the question body in one continuous statement
✅ Best Practices
Do's
- ✓Hide Only Decorative Elements
- ✓Group Related Items
Don'ts
- ✗Expose unnecessary and decorative icons to VoiceOver
- ✗Use fixed heights for text containers
🔍 Common Pitfalls
Fixed Heights
Using fixed heights can cause text to be cut off
Nested ScrollViews
Can cause scrolling issues with large text
Image Text
Text in images doesn't scale with user preferences
Custom Fonts
May not scale properly if not implemented correctly
🧪 Testing Steps
- 1Enable Large Text: Go to Settings > Accessibility > Font size
- 2Set Maximum Scale: Move slider to largest setting
- 3Test Your App: Navigate through all screens
- 4Verify Layout: Ensure text doesn't overflow or get cut off
- 5Check Readability: Text should remain clear and readable
📱 Assistive Technology Behavior
TalkBack
Will read text at the user's preferred font size
Magnification
Works in conjunction with font scaling
Switch Access
Navigation remains functional with scaled text