Conflicting Traits
Views should not have conflicting accessibility traits.
Impact
People using VoiceOver and Switch Control are most impacted. Conflicting traits may cause navigation gestures in assistive technology to become unresponsive. A control's role may be relayed to the user improperly because of a mismatched trait.
Confirmation
- Turn on VoiceOver
- Focus the element
- One of the following will happen:
- Inaccessible: VoiceOver will announce two conflicting roles (such as "Button" and "Link")
- Inaccessible: A VoiceOver navigation gesture will no longer work (such as using "Heading" and "Adjustable" together)
- Accessible: All roles make sense, and navigation gestures work as intended.
How to Fix
An improper selection of Accessibility Traits causes an issue found by this rule. Read more on Accessibility Traits in Apple's documentation for UIKit or SwiftUI.
UIKit
In storyboard:
- Select the accessibility element with conflicting accessibility traits.
- Ensure that the Inspector Panel is visible.
- Select the Identity Inspector.
- Under "Accessibility", there is a category called "Traits". Unselect the checkbox of the Accessibility Trait that is conflicting.
In code:
- Remove the conflicting accessibility trait. For example, a button may have the following Accessibility Traits:
button.accessibilityTraits = [.button, .link]
The button should only have one of them, depending on the button's context. In this case, the conflicting one was "link". To use a button as a link, remove the button trait for the desired behavior.
button.accessibilityTraits = .link
SwiftUI
While updating accessibility traits, ensure each trait reflects the proper usage of the control. For example, if a button mimics a link, you remove the default 'button' accessibility trait and add the 'link' trait.
var body: some View {
Button(action: { openLink() },
label: {
Text("Visit this Site!").padding()
})
.accessibility(addTraits: .isLink)
.accessibility(removeTraits: .isButton)
}