Ação Inacessível
Assegure que elementos interativos possam ser ativados com o VoiceOver
Esta é uma regra experimental e, portanto, seus resultados são considerados em fase de testes beta. Saiba mais sobre regras experimentais e como você pode ajudar a melhorá-las.
O que Verificamos
Um elemento interativo deve ser ativável por tecnologia assistiva. Esta regra verifica se a ação associada a um elemento interativo pode ser focada e acionada usando o VoiceOver.
Visão Geral
- Esta regra tem um impacto crítico para os usuários
- Esta regra sinaliza elementos interativos nos quais o VoiceOver não pode focar ou ativar
- Isso acontece quando um elemento não é focável por si só e não está dentro de um elemento pai focável
- Um elemento interativo que está dentro de um elemento pai focável é inacessível quando nenhuma ação, reconhecedor de gestos ou ponto de ativação é detectado
Impacto para os Usuários
Usuários de tecnologia assistiva são os mais impactados. Quando o VoiceOver pode focar em um elemento interativo, mas não pode ativá-lo, os usuários podem ficar impossibilitados de completar ações críticas - como enviar um formulário, alternar uma configuração ou navegar para outra tela. Isso cria uma barreira completa para pessoas que dependem exclusivamente do VoiceOver para interagir com o aplicativo.
Confirmar Problema de Ação Inacessível
- Ligue o VoiceOver
- Foque no elemento
- Uma das seguintes situações ocorrerá:
- Inacessível: O usuário não conseguirá ativar o elemento usando o VoiceOver
- Acessível: O usuário conseguirá usar o VoiceOver para ativar o elemento
Corrigir Problemas
Existem vários cenários que podem resultar em um problema de Ação Inacessível. A correção depende de como o elemento está estruturado. Revise as abordagens abaixo e use aquela que corresponde ao seu layout.
UIKit
Existem várias abordagens, dependendo de como o elemento está estruturado.
Correção no Storyboard — certifique-se de que o controle ativo é um elemento de acessibilidade:
- Selecione o elemento com um
InaccessibleActionproblema. - Certifique-se de que o Painel de Inspetores esteja visível.
- Selecione o Inspetor de Identidade.
- Em Acessibilidade, assegure-se de que a caixa "Habilitado" esteja selecionada para o controle ativo.
Uma opção alternativa é alterar o caminho de acessibilidade do elemento:
- Repita os passos 1–3 para o controle ativo, seu rótulo, e o elemento que o contém.
- Assegure-se de que a caixa "Habilitado" esteja selecionada apenas para o controle ativo, não para o rótulo ou o elemento que o contém.
- No código, atualize o caminho de acessibilidade para incluir tanto o rótulo quanto o controle ativo (veja a correção de caminho de acessibilidade no código abaixo).
Outra solução é centralizar o controle ativo dentro de seu elemento pai para que o ponto de ativação padrão do VoiceOver possa alcançá-lo:
- Selecione o elemento com um
InaccessibleActionproblema. - Certifique-se de que o Painel de Inspetores esteja visível.
- Selecione o controle ativo.
- Selecione o Inspetor de Tamanho.
- Certifique-se de que o controle ativo esteja centralizado horizontalmente e verticalmente dentro do seu elemento pai.
Correção no código:
Verifique se o controle ativo isAccessibilityElement está configurado para true:
buttonContainerView.isAccessibilityElement = trueAdicione um reconhecedor de gestos de toque à vista que o contém:
buttonContainerView.addGestureRecognizer(UITapGestureRecognizer(target: self, selector: #selector(buttonTapped)))Centralize o controle ativo dentro da vista principal para que o VoiceOver accessibilityActivationPoint dispare sua ação:
buttonContainerView.button.centerXAnchor.constraint(equalTo: buttonContainerView.centerXAnchor).isActive = true
buttonContainerView.button.centerYAnchor.constraint(equalTo: buttonContainerView.centerYAnchor).isActive = trueAtualize o caminho de acessibilidade para incluir tanto o rótulo quanto o controle ativo.
Defina isAccessibilityElement=false no rótulo e no elemento pai, para que apenas o próprio controle (o toggle, neste caso) seja um elemento de acessibilidade.
// 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
Esse problema não ocorrerá na maioria dos elementos e controles padrão no SwiftUI, mas pode ocorrer com controles personalizados ou quando elementos são agrupados incorretamente.
Ao construir controles personalizados que imitam o comportamento de um stepper, slider ou toggle, use .accessibilityRepresentation para dar ao controle personalizado o mesmo comportamento de acessibilidade do seu equivalente padrão:
// 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)")
})
}Ao agrupar vistas, use .accessibilityElement(children: .combine) ou .accessibilityElement(children: .contain) para garantir que todas as ações nos controles filhos permaneçam acessíveis:
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 a vista que o contém tiver um controle ajustável como um stepper ou slider, use .accessibilityAdjustableAction para proporcionar a melhor experiência de acessibilidade:
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
Esse problema é incomum para controles tocáveis ou pressionáveis padrão no React Native, mas pode ocorrer com controles personalizados.
Opção 1: Permitir que a vista pai gerencie o foco
Defina a propriedade da vista que o contém accessible para true e accessibilityElementsHidden para false, e atribua o(a) accessibilityRoleapropriado:
<View
accessible={true}
accessibilityElementsHidden={false}
accessibilityRole='link'
accessibilityLabel='Learn more about Deque'
onTouchStart={openLink}
>
<Image
source={DequeLogo}
style={{ width: 100, height: 100 }}
/>
</View>Opção 2: Permitir que o próprio elemento gerencie o foco
Defina accessible, accessibilityElementsHidden, e accessibilityRole diretamente no controle:
<Image
source={DequeLogo}
accessible={true}
accessibilityElementsHidden={false}
accessibilityRole='link'
accessibilityLabel='Learn more about Deque'
onTouchStart={openLink}
style={{ width: 100, height: 100 }}
/>Flutter
Os widgets Material do Flutter (ElevatedButton, IconButton, etc.) expõem ações de toque ao leitor de tela automaticamente. Ao construir elementos interativos personalizados com GestureDetector, envolva-os com MergeSemantics com um widget Semantics para garantir que o leitor de tela possa descobrir e ativar o elemento em uma única parada de foco.
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 ignorar esta regra?
A ação inacessível tem um impacto crítico para os usuários, e recomendamos fortemente a correção desses problemas. Como esta é uma regra experimental, você deve verificar os resultados manualmente. Se você confirmou que o elemento pode ser ativado pelo VoiceOver, pode ser aceitável ignorar o aviso. Saiba mais sobre ignorar regras.
Recursos
Páginas do Curso Deque University
Nota: O acesso completo aos recursos da Deque University requer uma assinatura.
Outros Recursos
- Diretrizes de Acessibilidade para Conteúdo Web (WCAG) 2.1, Recomendação W3C
- Documentos de Compreensão WCAG 2.1
