Improving accessibility for iOS apps with VoiceOver (Part 1)

Today I want to show you some practices that make your app accessible for VoiceOver users. VoiceOver provides spoken descriptions and braille output of onscreen elements.

Let’s go beyond the visuals to identify how VoiceOver can help improve the experience for all users. By encouraging VoiceOver use, you will be supporting 80% of accessibility tools, because they are all based on the same Accessibility API. Another advantage of supporting VoiceOver is UI Testing, which is also based on the same API.

Let’s dive into the implementation.

Generally, your app will already be supporting VoiceOver, because every UIKit component implements UIAccessibility protocol, which is the root type in Accessibility API. The protocol contains several properties which VoiceOver uses to identify, read and act with your User Interface, and I will be describing some of them below.

isAccessibilityElement indicates to VoiceOver whether this element should be read to the user or should be ignored by the system.

accessibilityLabel describes the current control’s content label. This label should be read by VoiceOver.

accessibilityValue describes the value of the control. For example, this property is used by UISlider and UIStepper to show the currently selected value.

accessibilityTraits specifies actions and helps communicate to users how they can interact with this component. For instance, UILabel has a static Text trait which means this element can’t interact, and VoiceOver can only read this component’s content. UIButton has a button trait which means the user can tap on it and cause some response.

If you are using Interface Builder to create the UI you can edit these properties in Identity Inspector, enable VoiceOver on your phone and run the app to check out what you have out of the box. In the case of creating your UI via code, you have to enable isAccessibilityElement property manually for views which you want to be accessible.

Grouping accessibility elements

Sometimes it’s helpful to group UIKit controls into the single accessibility element on which VoiceOver will act as a single component. For example, let’s take a look at our Meet Magento conference app, where we have an agenda with the list of presentations and breaks for every day of the conference.

Here we have UITableView populated with PresentationCells. In the case of PresentationCell,we want VoiceOver to focus and act on entire the cell and not on every label inside. To achieve this we have to enable isAccessibilityElement on the cell itself which will disable accessibility for every control inside. Let’s dive into the code sample:

We enable accessibility in awakeFromNib method and we also set the trait to button, as this will help VoiceOver to understand that the cell is clickable.

Every cell in our app has a ViewModel which formats data for the cell. To specify which data should be used by VoiceOver, we create an Accessible protocol which is implemented in PresentationViewModel.

As you can see, the Accessible protocol gives us the opportunity to define VoiceOver data without mixing formatting logic and accessibility logic. As soon as the cell is focused by VoiceOver, it will read to the user this phrase: “\(label). \(value). Button.”

In future posts, I will show you how to handle accessibility gestures in custom views and how to implement Custom Rotors navigation.

Thanks for reading this post. Now it’s time to work on making your own projects accessible!