Accessibility

VoiceOver and Labels

All interactive elements must be perceivable to assistive technologies.

Provide meaningful labels and hints.

Example

SwiftUI

import SwiftUI

struct ContentView: View {
  @State private var count = 0
  var body: some View {
VStack(spacing: 12) {
  Text("Count: \(count)")
    .accessibilityLabel("Current count")
    .accessibilityValue("\(count)")
  Button("Increment") { count += 1 }
    .accessibilityHint("Increases the count by one")
}
.padding()
} }

In this example, the count is perceivable through both label and value.


Dynamic Type and Contrast

Use system text styles (e.g., .font(.body)) and check color contrast.

Respect reduced motion and increased contrast settings.

Tip: Test with VoiceOver, Larger Text, Bold Text, and different Appearance (Light/Dark).

Use the Accessibility Inspector in Xcode.


Semantics & Traits

Expose clear semantics and traits so assistive tech understands your UI.

Example

Semantics.swift

import SwiftUI

struct PlanBadge: View {
  var body: some View {
VStack {
  Image(systemName: "star.fill")
    .foregroundStyle(.yellow)
    .accessibilityLabel("Favorite")
    .accessibilityAddTraits(.isImage)
  Text("Premium plan")
}
// Read as one element: "Favorite, Premium plan"
.accessibilityElement(children: .combine)
} }

In the example above, the image is exposed as an image and the text as a label.


Focus, Order & Grouping

Control reading order and group related elements.

Example

Order.swift

import SwiftUI

struct TotalRow: View {
  var total: Double
  var body: some View {
HStack {
  Text("Total")
    .accessibilitySortPriority(2)
  Text(total, format: .currency(code: Locale.current.currency?.identifier ?? "USD"))
    .accessibilitySortPriority(1)
}
// Alternatively, combine for a single announcement
// .accessibilityElement(children: .combine)
} }

In the example above, the total is read as one element.


Custom Actions

Expose adjustable and named actions to VoiceOver users.

Example

Actions.swift

import SwiftUI

struct QuantityStepper: View {
  @State private var qty = 1
  var body: some View {
Stepper("Quantity: \(qty)", value: $qty)
  .accessibilityValue("\(qty)")
  .accessibilityAdjustableAction { direction in
    switch direction {
    case .increment: qty += 1
    case .decrement: qty = max(0, qty - 1)
    default: break
    }
  }
  .accessibilityAction(named: Text("Reset")) { qty = 1 }
} }

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *