iOSinput-navigationIntermediate

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

  1. 1Enable Large Text: Go to Settings > Accessibility > Font size
  2. 2Set Maximum Scale: Move slider to largest setting
  3. 3Test Your App: Navigate through all screens
  4. 4Verify Layout: Ensure text doesn't overflow or get cut off
  5. 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