Best practice to build accessible apps with SwiftUI

Created: Apr 7, 2021 2:25 PM

Last year I had the opportunity to learn SwiftUI development and specifically to work on making views more accessible. At that time, I’ve set up for the team a list of best practices. Today, I’ve decided to share those wit…


This content originally appeared on DEV Community and was authored by Fanny Demey

Created: Apr 7, 2021 2:25 PM

Last year I had the opportunity to learn SwiftUI development and specifically to work on making views more accessible. At that time, I've set up for the team a list of best practices. Today, I've decided to share those with you.

How VoiceOver works

First let's see how VoiceOver works. VoiceOver is the screen reader used on iOS by users with low vision or who are blind. Here are several gestures that you can perform anywhere on the screen, that allows you to navigate through visual elements :
➡️ swipe to the right to go to next element

⬅️ swipe to the left to go to previous element

⬇️ ⬆️ swipe top to bottom or bottom to top allows you to do an action that you can configure with the rotor (see below)

? drawing a circle with 2 fingers will open what is called the "Rotor". It allows you to configure swipe action top <-> bottom, for example : Navigation between headers or containers.

Rotor gesture on an iPhone

? single tap on an item to read an element.

?? double tap to activate an element for example a button.

When an element is focused, VoiceOver will give user information about it. Basically VoiceOver read 4 properties for each element :

  1. Label : for exemple the text of the element "Today"
  2. Value : "Wednesday 8th of July" (it can be a complementary information. It's not mandatory, but can be useful for EditText for example).
  3. Trait : "Button" or "Static text" or "Heading" or "Container" or "Adjustable"
  4. Hint : To give a hint to the user about the action that can be performed on this element. for exemple "swipe top or bottom to change the value of this element" (not mandatory also)

Those 4 properties are pronounced in this order.

How I test accessibility

One good practice I applied to make my application usable for people with visual impairment was testing 2 different use cases :

  1. Use VoiceOver and validate that the user experience is good ?
  2. Test my application with different font size in accessibility parameters ? (that can be done easily with the Accessibility Inspector. You can find it in XCode menu ⇒ Open Developer Tool ⇒ Accessibility inspector)

Screenshot of Accessibility Inspector from Xcode

Of course, there are other use case to make an app accessible, and visual impairment is not the only thing you should care about.

Use case 1 : using VoiceOver ?

Here are some test I perform to test user experience with VoiceOver :

  • User can easily go from an element to another, and the order of element is logical
  • User can identify the goal of an element thanks to a good combination of label / value / trait / hint
  • VoiceOver do not focus on decorative element such as image background.
  • Some element are grouped to facilitate comprehension and navigation (for example : an icon and its label)
  • If using modal view, make sure that the content underneath is not accessible throw VoiceOver

Use case 2 : change font size ?

Here are some test I perform for this use case :

  • Texts scale when changing for a larger font in accessibility settings
  • User can still see all content
  • Nothing overlaps

Best practice list

When my test fail, most of the time I use a solution from the following list :

1/ Make font scalable

If you have trouble having your font scaling up with accessibility settings, you should probably take a look at this tutorial : https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-dynamic-type-with-a-custom-font

2/ Change reading order with voiceOver

In some situation I had to tell VoiceOver which element to focus on before another one.

HStack {
    buttons().accessibility(sortPriority: 1)
    chevron().accessibility(sortPriority: 2)
}.accessibilityElement(children: .contain)

In this example, chevron will have focus before buttons when user navigate between elements with VoiceOver.

3/Combine element together

To avoid user to navigate to all single piece of elements when its not needed, I group element together and set a specific label for this group.

HStack{
    Button(....)
    Text(.....)
}.accessibilityElement(children: .combine)
.accessibility(label: Text("Title"))

Example :

Example of a image button group with its label with VoiceOver

4/ Change trait type

In some situation, I wanted had to add or remove a trait :

Text(title)
  .accessibility(addTraits: .isHeader)
  .accessibility(removeTraits: .isStaticText)

5/ Disable visibility of an element

A good practice in accessibility is to hide decorative element such as background image.

HStack(){
    //... 
}.background(
        Image(I.home_nav_background)
            .accessibility(hidden: true)
)

6/ Add more explicit label

For example, in my app I displayed a time in this format HH:mm. To make it more understandable with VoiceOver, I had to override the label of the Text (overwise VoiceOver was saying something like "HH colon mm")

Text(hour)
.accessibility(label: Text(hour.toSpelloutAccessibleTime(format : "HH:mm")))

7/ Adapt design when font become larger

It can be useful t to adapt design when the font become larger. Here is how I've done it.

@SwiftUI.Environment(\\.sizeCategory) var sizeCategory: ContentSizeCategory

// Then you can simple use greater than and less than comparator to change property values for example
HStack{
    // 
}.frame(height: sizeCategory > .extraLarge  ? 100 : 40)

Conclusion

That's it for the best practices I've tried to applied when I was developing on SwiftUI last year. The Swift API have probably evolved by now, so my best advice for SwiftUI beginner like I was (and that I actually still are as I am an android developer) is to learn from Hacking with swift website. There is a series of article about accessibility : https://www.hackingwithswift.com/books/ios-swiftui/accessibility-introduction

If you are not familiar with accessibility and the usage of VoiceOver, I also advice you to try VoiceOver on a real device. You can have a look to this video to learn more about how to use VoiceOver on your iPhone

I Hope my personal best practice will help you. Don't hesitate to reach out on Twitter : @FannyDemey


This content originally appeared on DEV Community and was authored by Fanny Demey


Print Share Comment Cite Upload Translate Updates
APA

Fanny Demey | Sciencx (2021-04-07T18:16:23+00:00) Best practice to build accessible apps with SwiftUI. Retrieved from https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/

MLA
" » Best practice to build accessible apps with SwiftUI." Fanny Demey | Sciencx - Wednesday April 7, 2021, https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/
HARVARD
Fanny Demey | Sciencx Wednesday April 7, 2021 » Best practice to build accessible apps with SwiftUI., viewed ,<https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/>
VANCOUVER
Fanny Demey | Sciencx - » Best practice to build accessible apps with SwiftUI. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/
CHICAGO
" » Best practice to build accessible apps with SwiftUI." Fanny Demey | Sciencx - Accessed . https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/
IEEE
" » Best practice to build accessible apps with SwiftUI." Fanny Demey | Sciencx [Online]. Available: https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/. [Accessed: ]
rf:citation
» Best practice to build accessible apps with SwiftUI | Fanny Demey | Sciencx | https://www.scien.cx/2021/04/07/best-practice-to-build-accessible-apps-with-swiftui/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.