ignored-by-assistive-technology

Screen readers should be able to navigate to this element.

Who might be affected
Low Vision
Screen Reader

Description

Make sure each interactive element can receive VoiceOver focus. If it cannot, assistive technology users cannot reach or use it.

Ensure only the element is marked as an accessible element, not it’s container. If an element includes custom actions, isAccessible must be set to true.

Patterns

iOS

UIKit (Fail techniques)

1// UIKit - Interactive Views
2let button = UIButton(type: .system)
3button.setTitle("Text Button", for: .normal)
4button.isAccessibilityElement = false // Prevents VoiceOver focus
1// SwiftUI - Interactive Views
2Button("Text Button") {}
3 .accessibilityHidden(true) // Prevents VoiceOver focus
1// UIKit - Non-interactive views with custom accessibility actions
2let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
3imageView.image = UIImage(systemName: "photo.on.rectangle.angled")
4imageView.isAccessibilityElement = false // Prevents VoiceOver focus
5imageView.accessibilityCustomActions = [
6 UIAccessibilityCustomAction(name: "Share") { _ in true }
7]
1// SwiftUI - Non-interactive views with custom accessibility actions
2Image(systemName: "photo.on.rectangle.angled")
3 .resizable()
4 .scaledToFit()
5 .frame(width: 44, height: 44)
6 .accessibilityAction(named: "Show details") { }
7 .accessibilityHidden(true) // Prevents VoiceOver focus
1// UIKit - Non-interactive container with custom actions
2let stackView = UIStackView()
3
4// In case of assigning custom actions to container like stack view,
5// for VoiceOver it is necessary to get focus of the container in order
6// to present the actions to the user.
7stackView.accessibilityCustomActions = [
8 UIAccessibilityCustomAction(name: "Primary Action") { _ in true },
9 UIAccessibilityCustomAction(name: "Secondary Action") { _ in true }
10]
11
12stackView.isAccessibilityElement = false // Prevents VoiceOver focus (custom actions are not reachable)
13
14let primaryButton = UIButton(type: .system)
15primaryButton.setTitle("Primary Button", for: .normal)
16primaryButton.isAccessibilityElement = true
17
18
19let secondaryButton = UIButton(type: .system)
20secondaryButton.setTitle("Secondary Button", for: .normal)
21secondaryButton.isAccessibilityElement = true
22
23stackView.addArrangedSubview(primaryButton)
24stackView.addArrangedSubview(secondaryButton)
1// SwiftUI - Non-interactive container with custom actions
2VStack {
3 Button("Container child button") {}
4 Toggle("Container child toggle", isOn: $isOn)
5 .labelsHidden()
6}
7.accessibilityElement(children: .ignore)
8// In case of assigning custom actions to container like stack,
9// for VoiceOver it is necessary to get focus of the container in order
10// to present the actions to the user.
11.accessibilityAction(named: "Custom Action", {})
12.accessibilityHidden(true)

UIKit (Pass techniques)

1// UIKit
2let button = UIButton(type: .system)
3button.setTitle("Text Button", for: .normal)
4button.isAccessibilityElement = true // Enables VoiceOver focus
1// SwiftUI
2Button("Text Button") {}
3 .accessibilityHidden(false) // Enables VoiceOver focus
1// UIKit - Non-interactive views with custom accessibility actions
2let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
3imageView.image = UIImage(systemName: "photo.on.rectangle.angled")
4imageView.isAccessibilityElement = true // Enables VoiceOver focus
5imageView.accessibilityCustomActions = [
6 UIAccessibilityCustomAction(name: "Share") { _ in true }
7]
1// SwiftUI - Non-interactive views with custom accessibility actions
2Image(systemName: "photo.on.rectangle.angled")
3 .resizable()
4 .scaledToFit()
5 .frame(width: 44, height: 44)
6 .accessibilityAction(named: "Show details") { }
7 .accessibilityHidden(false) // Enables VoiceOver focus
1// UIKit - Non-interactive container with custom actions
2let stackView = UIStackView()
3
4// In case of assigning custom actions to a container like stack,
5// for VoiceOver it is necessary to get focus of the container in order
6// to present the actions to the user.
7stackView.accessibilityCustomActions = [
8 UIAccessibilityCustomAction(name: "Primary Action") { _ in true },
9 UIAccessibilityCustomAction(name: "Secondary Action") { _ in true }
10]
11
12stackView.isAccessibilityElement = true // Enables VoiceOver focus on the container (custom actions are reachable)
13
14let primaryButton = UIButton(type: .system)
15primaryButton.setTitle("Primary Button", for: .normal)
16
17let secondaryButton = UIButton(type: .system)
18secondaryButton.setTitle("Secondary Button", for: .normal)
19
20stackView.addArrangedSubview(primaryButton)
21stackView.addArrangedSubview(secondaryButton)
1// SwiftUI - Non-interactive container with custom actions
2VStack {
3 Button("Container child button") {}
4 Toggle("Container child toggle", isOn: .constant(false))
5 .labelsHidden()
6}
7
8.accessibilityElement(children: .ignore)
9.accessibilityAction(named: "Custom Action", {})
10.accessibilityHidden(false) // Enables VoiceOver focus on the container (custom actions are reachable)

WCAG Success criteria

This issue might cause elements to fail one or more of the following Success criteria:
1.3.1 Info and Relationships (A) | 2.4.3 Focus Order (A)