VoiceOver no iOS: cada controle se comporta de maneira diferente

Olá Habr! Recentemente, falei sobre a adaptação de aplicativos para pessoas cegas e imóveis. E não terminei!

Hoje vou lhe dizer como mudar o comportamento dos controles com a ajuda accessibilityTraitse tornar a vida dos cegos um pouco mais conveniente. É importante conhecer o trabalho dessas características para não escrever as muletas.



A adaptação do aplicativo iOS é um grande tópico, tudo não se encaixava em um artigo, então eu os libero em uma série.

  1. Controle por voz e VoiceOver: como adaptar o aplicativo para cegos ou imóveis .
  2. VoiceOver no iOS: cada controle se comporta de maneira diferente.
  3. VoiceOver no iOS: solução de problemas comuns.
  4. A diferença entre a implementação dos testes VoiceOver, Voice Control e UI. (Em progresso)

Na primeira parte, começamos a lidar com a adaptação de aplicativos para cegos usando o VoiceOver: controles assinados, agrupados, navegação fixa. Neste artigo, iremos além e consideraremos os "recursos" que podem ser fornecidos aos controles para melhorar seu trabalho para pessoas cegas e, geralmente, melhorar a usabilidade do aplicativo.

Recursos de controle - coleção de características


O VoiceOver possui um conjunto padrão de "recursos" UITraitCollectionque você pode aplicar aos controles. É importante saber sobre eles com antecedência, para não apresentar suas próprias soluções. Dividi-os em três tipos:

  1. Tipo de controle.
  2. O estado de controle.
  3. Propriedades especiais de controles.

Mostrarei imediatamente em um exemplo de tela com um cartão de pizza:



Tipo de controle


O VoiceOver conhece alguns tipos básicos de elementos. Alguns deles já estão configurados no seu projeto, mas eu vou falar sobre eles de qualquer maneira.

Os tipos de controle são usados ​​para a navegação: você pode navegar rapidamente por eles usando o rotor .

  • .staticText- para inscrições que não mudam. O texto é fácil de ler.
  • .header- cabeçalho: adicione à pizza, cabeçalho.
  • .buttonbotão A principal maneira de assinar controles ativos: Altere a composição, botão.
  • .image - cenário.
  • .link- ligação. Um convidado raro em aplicativos, frequente em sites.
  • .searchField Pesquise.

Vemos um exemplo:


  1. Indique o título. .staticTextdefinido automaticamente para todos os rótulos, mas .headerpara o título, você precisa colocá-lo manualmente. Quando esta necessidade e .headere .staticText.
  2. Marque o local abaixo da foto. Da última vez que ocultamos todas as imagens pequenas do VoiceOver, não perdemos conteúdo informativo. Desta vez, a imagem é grande, não é tão fácil de esconder: o local ficará vazio, isso é estranho. Marcamos a imagem conforme a .imageassinamos .accessibilityLabel = " ".

Obviamente, os botões de fechar e a cesta devem ser assinados, isso foi no último artigo.

Status de controle


O controle pode ter três estados: normal, selecionado e desativado. É interessante que eles sejam pronunciados em momentos diferentes e possam ser selecionados ao mesmo tempo:



  • .selected- adiciona "selecionado" na frente do nome do controle. Adequado para todos os interruptores e caixas de seleção.
  • .notEnabled- adiciona "indisponível". Essa configuração não é visível Interface Buildere é controlada apenas programaticamente.

Um exemplo de adição de coberturas à pizza:


Usando estados, você pode explicar ao usuário que a cobertura foi adicionada. É conveniente consertar dentro da célula. accessibilityTraitsisso OptionSeté porque inserção .formUnione excluir métodos podem ser aplicados a ele .formIntersection:

class ToppingCell: UICollectionViewCell {
    override var isSelected: Bool {
        didSet {
            if isSelected {
                accessibilityTraits.formUnion(.selected)
            } else {
                accessibilityTraits.formIntersection(.selected)
            }
        }
    }
    ...
}

Propriedades especiais de controles


Existem algumas propriedades mais incomuns. No nosso caso, eles não se encaixam na tela da pizza, mas eu ainda falarei sobre eles, porque não há informações suficientes sobre eles. Talvez isso economize seu tempo.

  • .summaryElement — , . , , . , .
  • .updatesFrequently —  . .
  • .causesPageTurn —  . accessibilityScroll(.next) , . .firstResponder.
  • .startsMediaSession —  VoiceOver , . , . , VoiceOver .
  • .playsSound —  , ( , ).
  • .allowsDirectInteraction- para desenhar e manipular gestos. O controle processa imediatamente o toque como se o VoiceOver estivesse desativado.
  • .keyboardKey- o controle começa a reagir como um botão no teclado. O VoiceOver possui vários modos de entrada de texto para esses casos:

    - standart typing- como um simples botão no VoiceOver: primeiro foque na letra e toque duas vezes em qualquer lugar para escrevê-la. Você pode digitar mais rápido com as duas mãos: conduza o teclado com um dedo (as letras serão expressas) e toque com o outro dedo para confirmar a seleção da tecla.
    - touch typing- Discagem rápida com um braço: passe o dedo pelo teclado para obter os botões de voz. Solte o dedo para escrever a carta.
    - direct touch typing- como um aparelho comum, como se o VoiceOver estivesse desligado.

Vídeo sobre diferentes métodos de entrada:


Basta marcar a caixa IB para adicionar comportamento. Com a característica .adjustable, não será tão fácil, separadamente.

Configurando a poderosa característica ajustável


E a última, característica especialmente importante .adjustableé um elemento que pode ser regulada: é assim UISteppere trabalho UISlider. Passe este controle para cima ou para baixo para alterar o valor (não esqueça que deslizar para a esquerda / direita mudará o foco para o elemento vizinho). Se o controle tiver um UIPanGestureRecognizer, você poderá tocar duas vezes e segurar o segundo toque, para que o gesto funcione e você possa controlá-lo diretamente, como se o VoiceOver estivesse desativado.

Exemplos de aplicação para .adjustable:

Chave de teste. A configuração do teste consiste em cinco botões: três para escolher o tamanho da pizza e dois para o tipo de teste. Eles devem ser agrupados e assinados para que, em vez de cinco, restem dois: “Tamanho, média. Item de ajuste " e“Massa tradicional. Item de ajuste ".



Precisa fazer em 4 etapas:

  1. Disponibilize o recipiente com os botões.
  2. Coloque uma característica .adjustable.
  3. Implementar métodos de aumento e redução.
  4. Retorne o novo valor para .accessibilityValue.

override public func awakeFromNib() {
        super.awakeFromNib()
        
        isAccessibilityElement = true // 1
        accessibilityTraits = .adjustable // 2
    }


extension SegmentedControl {
    override public func accessibilityIncrement() { // 3
        controller.selectNext(increment: +1)
    }
    
    override public func accessibilityDecrement() { // 3
        controller.selectNext(increment: -1)
    }
    
    public override var accessibilityValue: String? { // 4
        get {
            return selectedSegment?.accessibilityValue
        } set { }
    }
}

Agora, depois que um furto é chamado accessibilityIncrement(), você aumentará o contador interno e o VoiceOver lerá o novo valor da accessibilityValue.

Contagem total de valores. Neste bloco, vemos quatro controles: botão menos, quantidade, botão mais e preço. Você pode combiná-los em um viewe transformá-los em um controle: “Quantidade, 1, 575 rublos. Item de ajuste ". Após um furto vertical, a quantidade será alterada e um novo valor será pronunciado junto com o preço.



Horizontal UICollectionView. Descobriu-se que é .adjustableconveniente solicitar a horizontal UICollectionView. Por exemplo, escolha um compartilhamento no menu ou um carro em um táxi.



Conclusão


Desta vez, identificamos os traços: seus tipos, estados e comportamento. Este é um conjunto padrão para tarefas comuns . Para controles complexos, você pode usar .adjustable.

Da próxima vez, vamos olhar para uma solução para problemas comuns : ignorar ordem, janelas modais, carregar indicadores.

Para não perder o próximo artigo, assine o meu canal Dodo Pizza Mobile .

E agora temos uma vaga na direção móvel. Então, apenas deixo aqui: desenvolvedor iOS sênior (Nizhny Novgorod).


All Articles