Azione Inaccessibile

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard

Assicurati che gli elementi interattivi possano essere attivati con VoiceOver

Not for use with personal data
note

Questa è una regola sperimentale e quindi i suoi risultati sono considerati in fase di beta testing. Scopri di più sulle regole sperimentali e su come puoi contribuire a migliorarle.

WCAG 2.0 - 2.1.1 A Impact - Critical

Cosa Controlliamo

Un elemento interattivo dovrebbe essere attivabile tramite tecnologia assistiva. Questa regola verifica che l'azione associata a un elemento interattivo possa essere focalizzata e attivata utilizzando VoiceOver.

Esempio di Errore ❌

An iOS Settings screen with a Notifications toggle focused by VoiceOver (red border). VoiceOver announces 'Notifications, on.' with no activation hint, indicating the action cannot be triggered.

VoiceOver può focus attivare l'interruttore 'Notifiche' ma cannot activate it

VoiceOver annuncia "Notifications, on." - non viene fornito alcun ruolo o suggerimento di attivazione

Il doppio tap non ha alcun effetto; gli utenti non hanno modo di attivare l'impostazione

Esempio di Successo ✅

An iOS Settings screen with a Notifications toggle focused by VoiceOver (green border). VoiceOver announces 'Notifications, switch button, on. Double-tap to activate.' indicating the action is accessible.

VoiceOver può focus and activate attivare l'interruttore 'Notifiche'

VoiceOver annuncia "Notifications, switch button, on. Double-tap to activate."

Il ruolo e il suggerimento di attivazione sono presenti; gli utenti sanno esattamente come interagire con il controllo

In Sintesi

  • Questa regola ha un impatto critico per gli utenti
  • Questa regola segnala gli elementi interattivi su cui VoiceOver non può focalizzarsi o attivarsi
  • Ciò accade quando un elemento non è focalizzabile di per sé e non si trova all'interno di un genitore focalizzabile
  • Un elemento interattivo che si trova all'interno di un genitore focalizzabile è inaccessibile quando non viene rilevata alcuna azione, riconoscimento del gesto o punto di attivazione

Impatto sugli Utenti

Gli utenti della tecnologia assistiva sono i più colpiti. Quando VoiceOver può focalizzarsi su un elemento interattivo ma non può attivarlo, gli utenti potrebbero non essere in grado di completare azioni critiche - come inviare un modulo, attivare un'impostazione o navigare a un'altra schermata. Questo crea una barriera completa per le persone che si affidano esclusivamente a VoiceOver per interagire con l'app.

Conferma il Problema di Azione Inaccessibile

  1. Attiva VoiceOver
  2. Focalizza l'elemento
  3. Una delle seguenti opzioni si verificherà:
    • Inaccessibile: L'utente non potrà attivare l'elemento usando VoiceOver
    • Accessibile: L'utente potrà usare VoiceOver per attivare l'elemento

Risolvi i Problemi

Ci sono vari scenari che possono portare a un problema di Azione Inaccessibile. La soluzione dipende da come l'elemento è strutturato. Esamina gli approcci di seguito e utilizza quello che corrisponde al tuo layout.

UIKit

Ci sono diversi approcci, a seconda di come l'elemento è strutturato.

Correggi in Storyboard — assicurati che il controllo attivo sia un elemento di accessibilità:

  1. Seleziona l'elemento con un problema di InaccessibleAction.
  2. Assicurati che il Pannello degli Ispettori sia visibile.
  3. Seleziona il Ispettore Identità.
  4. Sotto Accessibilità, assicurati che la casella "Abilitato" sia selezionata per il controllo attivo.

Un'altra opzione è cambiare il percorso di accessibilità dell'elemento:

  1. Ripeti i passaggi 1–3 per il controllo attivo, la sua etichetta e l'elemento contenitore.
  2. Assicurati che la casella "Abilitato" sia selezionata solo per il controllo attivo, non per l'etichetta o l'elemento contenitore.
  3. Nel codice, aggiorna il percorso di accessibilità per includere sia l'etichetta che il controllo attivo (vedi la correzione del percorso di accessibilità nel codice qui sotto).

Un'altra soluzione è centrare il controllo attivo all'interno del suo genitore in modo che il punto di attivazione predefinito di VoiceOver possa raggiungerlo:

  1. Seleziona l'elemento con un problema di InaccessibleAction.
  2. Assicurati che il Pannello degli Ispettori sia visibile.
  3. Seleziona il controllo attivo.
  4. Seleziona la Ispettore delle dimensioni.
  5. Assicurati che il controllo attivo sia centrato orizzontalmente e verticalmente all'interno dell'elemento contenitore.

Correggi nel codice:

Assicurati che il isAccessibilityElement del controllo attivo sia impostato su true:

buttonContainerView.isAccessibilityElement = true

Aggiungi un riconoscitore di gesti tap alla vista contenitore:

buttonContainerView.addGestureRecognizer(UITapGestureRecognizer(target: self, selector: #selector(buttonTapped)))

Centra il controllo attivo all'interno della vista padre in modo che il accessibilityActivationPoint di VoiceOver attivi la sua azione:

buttonContainerView.button.centerXAnchor.constraint(equalTo: buttonContainerView.centerXAnchor).isActive = true
buttonContainerView.button.centerYAnchor.constraint(equalTo: buttonContainerView.centerYAnchor).isActive = true

Aggiorna il percorso di accessibilità per includere sia l'etichetta che il controllo attivo.

Imposta isAccessibilityElement=false sull'etichetta e sull'elemento padre, in modo che solo il controllo stesso (il toggle, in questo caso) sia un elemento di accessibilità.

// 1. Only the toggle should be an accessibility element
toggleContainerView.toggle.isAccessibilityElement = true
toggleContainerView.label.isAccessibilityElement = false
toggleContainerView.isAccessibilityElement = false

// 2. Expand the toggle's accessibilityPath to encompass the full container
// so VoiceOver's focus ring covers both the label and the toggle
let containerFrame = toggleContainerView.superview!.convert(toggleContainerView.frame, to: toggleContainerView.superview)
toggleContainerView.toggle.accessibilityPath = UIBezierPath(rect: containerFrame)

SwiftUI

Questo problema non si verificherà sulla maggior parte degli elementi e controlli predefiniti in SwiftUI, ma può verificarsi con controlli personalizzati o quando gli elementi sono raggruppati in modo errato.

Quando si costruiscono controlli personalizzati che imitano il comportamento di uno stepper, di un cursore o di un toggle, utilizza .accessibilityRepresentation per dare al controllo personalizzato lo stesso comportamento di accessibilità del suo corrispondente standard:

// Add .accessibilityRepresentation on a custom Toggle view
HStack {
    Text("Dark mode is \(getDarkModeStatus().localized)")
    Image(systemName: getDarkModeImage())
}.onTapGesture {
    isOn.toggle()
}
.accessibilityRepresentation {
    Toggle(isOn: $isOn, label: {
        Text("Dark mode is \(getDarkModeStatus().localized)")
    })
}

Quando si raggruppano le visualizzazioni, utilizza .accessibilityElement(children: .combine) o .accessibilityElement(children: .contain) per garantire che tutte le azioni sui controlli figlio rimangano accessibili:

VStack(alignment: .leading) {
    Text("Adjust settings below")
        .accessibilityElement(children: .ignore)
    Divider()
    Toggle(isOn: $isOn) {
        Text("Dark Mode is \(toggleStateText())")
    }
    .accessibility(value: Text("Dark Mode is \(toggleStateText())"))
}
.accessibilityElement(children: .combine)
.accessibilityLabel(Text("Adjust settings below"))

Se la vista contenitore ha un controllo regolabile come uno stepper o un cursore, utilizza .accessibilityAdjustableAction per fornire la migliore esperienza di accessibilità:

VStack {
    Text("Adjust the stepper below to update dog petting data".localized)
    Divider()
    HStack {
        Stepper(value: $value) {
            Text("Total dogs pet today \($value.wrappedValue)")
        }.accessibilityElement(children: .ignore)
    }
}
.accessibilityElement(children: .combine)
.accessibilityValue(Text("\($value.wrappedValue)"))
.accessibilityAdjustableAction({ direction in
    switch direction {
    case .increment:
        value += 1
    case .decrement:
        value -= 1
    @unknown default:
        print("unknown direction used")
    }
})

React Native

Questo problema è raro per i controlli standard touchable o pressable in React Native, ma può verificarsi con controlli personalizzati.

Opzione 1: Consenti alla vista padre di gestire il focus

Imposta la proprietà accessible della vista contenitore su true e accessibilityElementsHidden su false, e assegna il accessibilityRole appropriato:

<View
  accessible={true}
  accessibilityElementsHidden={false}
  accessibilityRole='link'
  accessibilityLabel='Learn more about Deque'
  onTouchStart={openLink}
>
  <Image 
    source={DequeLogo}
    style={{ width: 100, height: 100 }} 
  />
</View>

Opzione 2: Consenti all'elemento stesso di gestire il focus

Imposta accessible, accessibilityElementsHidden e accessibilityRole direttamente sul controllo:

<Image
  source={DequeLogo}
  accessible={true}
  accessibilityElementsHidden={false}
  accessibilityRole='link'
  accessibilityLabel='Learn more about Deque'
  onTouchStart={openLink}
  style={{ width: 100, height: 100 }}
/>

Flutter

I widget Material di Flutter (ElevatedButton, IconButton, ecc.) espongono automaticamente le azioni tap al lettore schermo. Quando si costruiscono elementi interattivi personalizzati con GestureDetector, avvolgili in MergeSemantics con un widget Semantics per garantire che il lettore schermo possa scoprire e attivare l'elemento in un unico stop di focus.

MergeSemantics(
  child: Semantics(
    button: true,
    label: 'Archive item',
    child: GestureDetector(
      onTap: () {},
      child: Container(
        padding: const EdgeInsets.all(12.0),
        color: Colors.green.shade100,
        child: const Text('Archive item'),
      ),
    ),
  ),
)

Posso ignorare questa regola?

Un'azione inaccessibile ha un Impatto critico per gli utenti, e raccomandiamo fortemente di correggere questi problemi. Poiché questa è una regola sperimentale, dovresti verificare i risultati manualmente. Se hai confermato che l'elemento è attivabile da VoiceOver, potrebbe essere accettabile ignorare il rilievo. Scopri di più su ignorare le regole.

Risorse

Pagine dei corsi di Deque University

Nota: l'accesso completo alle risorse di Deque University richiede un abbonamento.

Altre Risorse