Upgrade to Pro — share decks privately, control downloads, hide ads and more …

No Touch(screen) Required: Voice & Keyboard Accessibility

No Touch(screen) Required: Voice & Keyboard Accessibility

Accessibility is a topic that I care deeply about. Making sure everyone can use a product is something we, involved in building products, should think about.

On Apple platforms, you may be familiar with features like dynamic type (different text sizes), dark mode, and maybe even VoiceOver and Switch Control. But things don't stop there.

With Voice Control and Full Keyboard Access, Apple has taken accessibility another step further, making interacting with your device without needing to touch it easier than ever. Let's take a look at these technologies — how they work, and how you can support them by leveraging accessibility APIs.

Bas Broek

May 19, 2022
Tweet

More Decks by Bas Broek

Other Decks in Programming

Transcript

  1. No (Touch)screen
    Required
    Voice & Keyboard
    Accessibility
    Bas Broek
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 1

    View full-size slide

  2. Today is a special
    day.
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 2

    View full-size slide

  3. Global
    Accessibility
    Awareness Day
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 3

    View full-size slide

  4. Bas Broek
    • iOS, Accessibility & more @
    WeTransfer
    • Previously macOS
    Accessibility / VoiceOver @
    Apple
    • Swift for Good co-author
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 4

    View full-size slide

  5. It's the right
    thing to do.
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 5

    View full-size slide

  6. If only it were
    that easy.
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 6

    View full-size slide

  7. "Evolution" of Accessibility
    on Apple platforms
    • VoiceOver, Switch Control
    • Voice Control
    • Full Keyboard Access
    • ... and more; think zoom, Dynamic Type, Reduce
    Motion etc.
    • ... as well as Dark Mode, Back Tap, Siri, haptics
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 7

    View full-size slide

  8. Two layers of
    accessibility
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 8

    View full-size slide

  9. Act I: VoiceOver
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 9

    View full-size slide

  10. UIKit
    accessibilityLabel
    accessibilityTraits
    accessibilityValue
    accessibilityHint
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 10

    View full-size slide

  11. UIKit
    accessibilityLabel - "Volume"
    accessibilityTraits - .adjustable
    accessibilityValue - "56%"
    accessibilityHint - "Swipe up or down to
    adjust."
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 11

    View full-size slide

  12. SwiftUI
    .accessibilityLabel("Volume")
    .accessibilityAdjustableAction { direction in }
    .accessibilityValue("50%")
    .accessibilityHint("Swipe up or down to
    adjust.")
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 12

    View full-size slide

  13. VoiceOver
    Demo
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 13

    View full-size slide

  14. VoiceOver
    Demo:
    "Normal" speed &
    Screen Curtain
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 14

    View full-size slide

  15. Act II: Voice
    Control
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 15

    View full-size slide

  16. accessibilityUserInputLabels
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 16

    View full-size slide

  17. !
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 17

    View full-size slide

  18. /// The default value for this property is an empty array
    /// unless the element is a UIKit control.
    /// In that case, the value is an array with
    /// an appropriate label, if different from `accessibilityLabel`.
    ///
    /// Use this property when the `accessibilityLabel` isn't appropriate for
    /// dictated or typed input.
    /// For example, an element that contains additional descriptive
    /// information in its `accessibilityLabel` can return a more concise label.
    ///
    /// The primary label is first in the array, optionally followed
    /// by alternative labels in descending order of importance.
    ///
    /// If this property returns an empty array or an invalid value,
    /// the system uses `accessibilityLabel` instead.
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 18

    View full-size slide

  19. /// The default value for this property is an empty array
    /// unless the element is a UIKit control.
    /// In that case, the value is an array with
    /// an appropriate label, if different from `accessibilityLabel`.
    ///
    /// Use this property when the `accessibilityLabel` isn't appropriate for
    /// dictated or typed input.
    /// For example, an element that contains additional descriptive
    /// information in its `accessibilityLabel` can return a more concise label.
    ///
    /// The primary label is first in the array, optionally followed
    /// by alternative labels in descending order of importance.
    ///
    /// If this property returns an empty array or an invalid value,
    /// the system uses `accessibilityLabel` instead.
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 19

    View full-size slide

  20. "TAP TO COPY LINK"
    "Tap 'tap to copy link'"
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 20

    View full-size slide

  21. "TAP TO COPY LINK"
    "Tap 'tap to copy link'"
    "Tap 'copy link'"
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 21

    View full-size slide

  22. "It's Complicated: Inside an
    A. Lange & Söhne Split-
    Seconds Chronograph"
    "Tap 'It's Complicated: Inside an A. Lange &
    Söhne Split-Seconds Chronograph'"
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 22

    View full-size slide

  23. "It's Complicated: Inside an
    A. Lange & Söhne Split-
    Seconds Chronograph"
    "Tap 'It's Complicated: Inside an A. Lange &
    Söhne Split-Seconds Chronograph'"
    "Tap 'article, 1'"
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 23

    View full-size slide

  24. UIKit
    copyLinkButton.accessibilityLabel =
    "Tap to copy link"
    copyLinkButton.accessibilityUserInputLabels = [
    "Copy link",
    "Copy"
    ]
    article.accessibilityLabel =
    "It's Complicated: Inside an A. Lange & Söhne Split-Seconds Chronograph"
    article.accessibilityUserInputLabels = [
    "Article",
    "News",
    article.accessibilityLabel
    ]
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 24

    View full-size slide

  25. SwiftUI
    .accessibilityLabel(
    "Tap to copy link"
    )
    .accessibilityInputLabels([
    "Copy link",
    "Copy"
    ])
    .accessibilityLabel(
    "It's Complicated: Inside an A. Lange & Söhne Split-Seconds Chronograph"
    )
    .accessibilityInputLabels([
    "Article",
    "News",
    "It's Complicated: Inside an A. Lange & Söhne Split-Seconds Chronograph"
    ])
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 25

    View full-size slide

  26. Demo
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 26

    View full-size slide

  27. Act III: Full
    Keyboard Access
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 27

    View full-size slide

  28. /// The default value for this property is an empty array
    /// unless the element is a UIKit control.
    /// In that case, the value is an array with
    /// an appropriate label, if different from `accessibilityLabel`.
    ///
    /// Use this property when the `accessibilityLabel` isn't appropriate for
    /// dictated or typed input.
    /// For example, an element that contains additional descriptive
    /// information in its `accessibilityLabel` can return a more concise label.
    ///
    /// The primary label is first in the array, optionally followed
    /// by alternative labels in descending order of importance.
    ///
    /// If this property returns an empty array or an invalid value,
    /// the system uses `accessibilityLabel` instead.
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 28

    View full-size slide

  29. !
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 29

    View full-size slide

  30. Demo
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 30

    View full-size slide

  31. Loopin' back
    • VoiceOver support gets you most of the way
    there
    • Adding Voice Control support will get you ±all
    the way
    • ... to also support Full Keyboard Access on
    iOS!
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 31

    View full-size slide

  32. One last thing...
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 32

    View full-size slide

  33. WeTransfer:
    Mission Accessible
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 33

    View full-size slide

  34. Thank you!
    @basthomas
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 34

    View full-size slide

  35. References
    • https://www.basbroek.nl/getting-started-
    voiceover
    • https://www.basbroek.nl/custom-tab-bar-
    accessibility
    • https://developer.apple.com/videos/play/
    wwdc2021/10120/
    • https://about.wetransfer.com/accessibility
    @basthomas, #GAAD, May 19, 2022 @ CocoaHeads Sydney 35

    View full-size slide