Advent of iOS Accessibility
Advent of iOS Accessibility
Starting something new: The Advent of iOS Accessibility. Twenty-four days of exploring some of the most common accessibility issues I’ve encountered, how to identify them, and—most importantly—how to fix them. Hope you enjoy the series!
Day 1
One of the accessibility issues I see more often in iOS apps, believe it or not, is unlabelled elements. This happens especially for buttons with an icon but no title. In those cases, you need to configure an accessibility label manually.
Day 2
Some recommendations for improving your accessibility labels: don’t add the element type, avoid redundancy and verbosity, localize…
Day 3
Anything representing a heading in the app should have the header trait. It allows for a faster way of exploring a screen and quickly jumping to the part of the app you are interested in. Screens should also start with a header.
Day 4
Important information is often conveyed visually through icons, badges, or progress bars… These details can easily be overlooked. Please make sure they’re part of your UI’s components' accessibility labels or values for a more inclusive experience.
Day 5
Images should either be decorative or have a proper accessibility label or alt text that describes them. If they’re decorative you can make it so they get skipped by assistive tech so it doesn’t get in the way of the experience.
Quick clarification on this one. It is probably not the best example of decorative images. I think these images should have alt text. But in my experience, most APIs won’t give you one for movie posters, music artwork, and things like that… And the point is that a random name just adds noise.
And another nuance. VoiceOver has a feature called Image Explorer. VoiceOver can recognise text, people and objects in images. So if you think that users can get value with this feature, you might want to consider exposing the image then.
Oh! And avoid images of text please!
Day 6
With regular buttons from UIKit or SwiftUI, you are all set. With complex views, headings, or table/collection view cells that, when selected, bring the user somewhere else in the app or perform an action, you’ll have to add the button accessibility trait yourself to convey users that it is an interactive component.
Day 7
Grouping elements when it makes sense can make a huge impact on easing navigation with some assistive technologies like VoiceOver, Switch Control, or Full Keyboard Access. It also helps on reducing redundancy.
In UIKit, this process consists of three steps:
- Setting the parent view as an accessible element: https://iosdev.space/@dadederk/109693895401281036
- Configure relevant accessibility label, value, traits and hints on the parent view: https://iosdev.space/@dadederk/109806337876803727
- If there are secondary actions within the grouped view, configure custom actions: https://iosdev.space/@dadederk/1097016
In SwiftUI, it might be as simple as using the .accessibilityElement(children:) modifier with the .combine accessibility child behaviour: https://iosdev.space/@dadederk/109932750048041110 If that doesn’t quite work as expected, try to tweak the internal views. If not, you can fall back to UIKit’s three step process.
Day 8
If a view has isAccessibilityElement to true, assistive tech won’t look for any of its subviews. That means that if there are any buttons inside, they won’t be accessible. You can add custom actions to be able to ‘interact’ with them.
Day 9
If you have interactions that are hidden or require complex gestures to be performed or that may conflict with VoiceOver, you need to provide alternative ways of executing these actions. Custom actions can help a lot of times, but not always.
Day 10
Toggles or UISwitches are often found separated from the label that precedes (and describes) them; with an unclear label; missing a value, trait, or hint; or even not being actionable at all.
Day 11
Have you ever seen VoiceOver randomly focusing on elements of the previous view when presenting a custom modal view? That can be fixed by letting the system know that the presented view is modal in terms of accessibility.
Day 12
Sometimes we may fail to update users of things changing on the screen in a perceivable way. Toasts and similar should be announced. We may want to make clear that some content on the screen changed or to update on a task’s progress.
Day 13
Sometimes, you may want to create a custom component, even if there is a similar one in UIKit or SwiftUI because you want to style it in a way that the default one won’t let you. Or add extra functionality. That’s fine, but please take into account that you may need a bit of extra work to make it accessible.
Day 14
iOS and Xcode provide a wide variety of tools and options to deal with color, and help us providing good color contrast ratios. From system colors that automatically support Increase Contrast, to high contrast (and light and dark mode) color asset variants, automatic checks with the Audit feature in the Accessibility Inspector, and even a built-in contrast calculator.
Day 15
Touch target sizes are recommended to be at least 44 x 44 points for better usability. Buttons in the navigation bar (especially when not using nav bar button items), dismiss buttons, and custom toolbars, are common examples that often fall below this size.
Day 16
A reminder that the more modes we use to convey important information, the more likely it is that all users will perceive it. Consider a combination. of color, icons, messages, sound, haptics, animations, etc.
Day 17
Check the traversal order of elements in your app. Sometimes the default top-left to bottom-right order might not be the most logical one. Sometimes you may consciously want to tweak the order. Other times, grouping is the answer.
If you want to find out more, we had an interesting conversation in Bluesky with Paul J. Adam, on the nuances of how to implement this.
Day 18
When building custom components, or if not relying on UIControl’s attributes to configure state, it can be easy to forget to specify the right accessibility traits. These are indispensable for a good experience with VoiceOver, Switch Control, Voice Control, Full Keyboard Access…
Day 19
This post is work in progress… One more sleep till the next tip! See you tomorrow!
You can also follow the series in: