Conflicting Traits

Link to Conflicting Traits copied to clipboard

Platform Guideline Impact - Critical

This rule prevents conflicts with assistive technologies by identifying accessibility elements and ensuring its accessibility traits are complementary.

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

  1. Turn on VoiceOver
  2. Focus the element
  3. 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

note

Requires the accessibility layer for accurate results. Learn how to load the accessibility layer here.

In storyboard:

  1. Select the accessibility element with conflicting accessibility traits.
  2. Ensure that the Inspector Panel is visible.
  3. Select the Identity Inspector.
  4. 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)
    }