Creating an Accessible Reading Experience

Session 248 WWDC 2019

The styling and layout of text is a hallmark feature of an outstanding reading experience. Technologies such as CoreText and TextKit give you the tools you need to create a great text layout. Learn how to make an equally great accessible experience for VoiceOver by adopting the accessibility reading content protocol, adding automatic page turning, and customizing speech output.

[ Music ]

Hello. Welcome to Creating a Great Accessible Reading Experience.

My name is Darren Minifie, and I'm an engineering manager on the Accessibility Team.

The hallmark for a great application is an outstanding user interface.

This extends to the layout and styling of text especially for apps whose primary focus is the presentation of long form readable content.

To implement a custom text layout you often need to turn to lower level technologies such as Core Text and TextKit.

In this session, you will learn the APIs and techniques you need to create an equally great accessible reading experience for VoiceOver.

We'll begin by talking about the reading content protocol.

You use this protocol to make your text content accessible.

Next, we'll talk about automatic page turning, which VoiceOver uses to turn the pages in your application.

Finally, we'll discuss the APIs you can use to customize the way VoiceOver speaks your content.

In the session, we'll use the following sample app to demonstrate these techniques.

The app is a simple page-based application where each page consists of an image, a title, a subtitle and some detail text.

To make your app accessible, you should first audit it with VoiceOver.

A convenient way to do this is to add VoiceOver to your accessibility shortcut.

You can do this by launching settings, tapping accessibility, scrolling down to accessibility shortcut and tapping VoiceOver.

Now depending on your hardware, you can press the home button or side button 3 times to quickly enable and disable VoiceOver.

Let's see how VoiceOver interacts with the sample app.

VoiceOver on.

[ Beeping ]

As I drag my finger across the screen, VoiceOver plays a sound effect indicating there is no content to be found.

Therefore, the first thing we need to do is make our text content accessible.

To make your content accessible, you should use the UIAccessibilityReadingContent Protocol.

This protocol consists of 4 core methods.

AccessibilityLineNumber(for point asks you to return the line number for a given touch location.

AccessibilityContent (forLineNumber and accessibilityFrame (forLineNumber asks for the text content and rect for a given line respectively.

Finally, accessibilityPageContent asks you to return the entire pages worth of content.

Let's see how we would implement the UIAccessibilityReadingContent Protocol in our sample app.

Each page in the sample app is represented by an instance of SessionItemView.

This view has 4 sub views; an image view, a title label, an identifier label and a session details view.

We additionally declare a layout enum.

This will help us in our method implementations that follow.

The first thing we need to do is make our page view an accessibility element.

We do this by setting isAccessibilityElement to true in the page views initializer.

Next, we begin to implement the reading content protocol.

Our first method is accessibilityLineNumber(for point.

First, we hitTest the page view using the past in line number.

If the resulting view is one of our known sub views, we map that to the value of our layout enum.

Finally, we return the rawValue as this is the representation VoiceOver understands.

Next to implement AccessibilityContent (forLineNumber, we begin by instantiating an instance of the layout enum.

We switch over the possible cases and map that to one of our known sub views.

Finally, we return accessibility label, which returns the text for that sub view.

The implementation of accessibilityFrame (forLineNumber is very similar.

We begin by creating a new instance of the layout enum with our given raw value.

We switch over the possible cases and map that to one of our known sub views.

Finally, we return accessibility frame, which represents the rect for a given line.

Finally, to implement accessibilityPageContent we gather together the text from our known sub views and return them as a single string.

Let's see how the app interacts with VoiceOver with the reading content protocol implemented.

Accessible drag-and-drop.

Session 241.

Drag-and-drop is a powerful API that allows apps to share and communicate data.

This time as I drag my finger across the screen VoiceOver speaks and highlights the corresponding text.

Next let's talk about automatic page turning.

When VoiceOver's read all command is invoked, it's expected that VoiceOver will be able to read all of your content from beginning to end.

This may require VoiceOver to turn pages in your app.

To implement automatic page turning you need to adopt 2 accessibility APIs.

First, you should include the causesPageTurn accessibility trait on your page view.

Second, you should implement AccessibilityScroll in direction.

This gives VoiceOver the ability to turn pages in your app.

Let's see how we would implement automatic page turning in our sample app.

First, we need to include the causesPageTurn accessibility trait.

We do this by setting accessibility trait in the page views initializer.

Next, we implement accessibilityScroll and direction.

We do this by switching over the possible cases of the direction parameter.

If the direction is previous or left, we ask our delegate to turn to the previous page.

If that's successful, we notify VoiceOver with a pageScrolled notification.

Similarly, if the value is right or next, we ask the delegate to turn to the next page and if that's successful, we notify VoiceOver with a pageScrolled notification.

Let's see how the app interacts with automatic page turning implemented.

Accessible drag-and-drop Session 241.

Drag-and-drop is a powerful API that allows apps to share and communicate data.

No matter how you decide to implant drag-and-drop there's a way to make it work for people with accessibility needs.

Learn the details as we dive into accessible drag-and-drop for iOS.

AVSpeechSynthesizer.

Making iOS talk.

Session 236.

Our final topic is customizing speech.

You may want to control the way VoiceOver speaks your app's content.

To do this you can use 2 alternate methods in the reading content protocol.

These method versions return NSAttributedStrings instead of simple strings.

By supplying the appropriate accessibility attributes, you can control various aspects about how VoiceOver speaks your content.

For example, you may have a passage you would like spoken in a particular language.

To do this you can include the accessibilitySpeechLanguage attribute along with the appropriate language identifier.

This causes VoiceOver to use the most appropriate voice to speak your content.

Arc de Triomphe.

Furthermore, you may want fine-grained control over the way VoiceOver speaks your content.

To do this you can supply the IPA representation for your passage along with the accessibilitySpeechIPANotation attribute.

Yosemite National Park.

So to create a great reading experience for VoiceOver, you first need to make your text content accessible.

You do this by implementing the UIAccessibilityReadingContent protocol.

Next, you should implement automatic page turning so VoiceOver can read all of the content in your app from beginning to end.

Finally, to control the way VoiceOver speaks your content, you should consider using the NS attributed strings versions of the methods in the reading content protocol and supply the appropriate accessibility attributes.

For more information about this topic, please visit the following session URL.

Thanks for watching.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US