This page is a collection of notes on implementing Accessibility in iOS. I think I’m going to split this out into multiple pages at some point. Just not yet.
Resources
Apple Guides
WWDC videos and slides
Sample Code
HelloGoodbye: Using the Accessibility API to Widen Your User Base
Accessibility APIs
Other useful references
http://www.solstice-mobile.com/blog/programming-for-ios-accessibility-voiceover
https://coderwall.com/p/sswchq/ios-custom-views-and-accessibility-in-table-views
http://useyourloaf.com/blog/2012/04/23/voiceover-accessibility.html
http://mattgemmell.com/accessibility-for-iphone-and-ipad-apps/
http://www.rosiesherry.com/2012/09/02/ios-accessibility-a-useful-guide-for-testing/
http://www.bbc.co.uk/guidelines/futuremedia/accessibility/mobile/developers
http://www.interactiveaccessibility.com/services/mobile-accessibility
ADA
http://www.access-board.gov/guidelines-and-standards/communications-and-it
Web Content Accessibility Guidelines (WCAG)
Implementing Accessibility
VoiceOver and UIViews
- Standard Views
- Containers
- UITableView
- Views with Dynamic Content
- Non-textual Data
Some implementation details we’ll need to pay attention to, from Accessibility from the View Controller’s Perspective
- Moving the VoiceOver Cursor to a Specific Element
- Responding to Special VoiceOver Gestures
- Observing Accessibility Notifications
Dynamic Type
Dynamic Type is not given as much attention as VoiceOver, but we should be paying attention to it. People in the know may be turning this on and ignoring other Accessibility features. For those of us whose eyes aren’t what they used to be, it’s kind of handy. See:
- Using Fonts in the iOS 7 UI Transition Guide
- Text Styles in the Text Programming Guide for iOS
A helper class from BNR which listens for the Dynamic Type change notification and updates all of your objects: Make iOS 7’s Dynamic Type Easier to Use with BNRDynamicTypeManager
Undoubtedly, we will need to resize table view cells when the type size changes. Prior to iOS 8, this is a pain. I haven’t looked closely at our code yet, so I don’t know how cell sizing is implemented.
Color Schemes and UI Modifications for Color Deficiencies and Low Vision
There are a lot of Accessibility features which modify the global color scheme for all of iOS, as well as features that alter the presentation of some UI elements. While we may not adapt the UI for most of these, it does make sense to turn them on and look at what our screens look like when these options are enabled.
- Invert Colors
- Grayscale (if you’re in the UK, does this say Greyscale?)
- Bold Text
- Button Shapes
- Increase Contrast
- Reduce Transparency
- Darken Colors
- Reduce White Point
- On/Off Labels
if we have custom switch controls, this may apply - Switch Control
don’t know if this uses the Accessibility order property to figure out the order of UI element selection
And with regards to animations:
- Reduce Motion
UIAccessibility Notifications
In order to adapt app behavior in response to changes in the Accessibility settings, iOS provides the following notifications. Associated global status methods, such as UIAccessibilityIsVoiceOverRunning() and UIAccessibilityIsInvertColorsEnabled() are provided as well. See <UIKit/UIAccessibility.h>
Available as of iOS 6
UIAccessibilityVoiceOverStatusChanged
UIAccessibilityMonoAudioStatusDidChangeNotification
UIAccessibilityClosedCaptioningStatusDidChangeNotification
UIAccessibilityInvertColorsStatusDidChangeNotification
UIAccessibilityGuidedAccessStatusDidChangeNotification
Available as of iOS 8.0
UIAccessibilityBoldTextStatusDidChangeNotification
UIAccessibilityGrayscaleStatusDidChangeNotification
UIAccessibilityReduceTransparencyStatusDidChangeNotification
UIAccessibilityReduceMotionStatusDidChangeNotification
UIAccessibilityDarkerSystemColorsStatusDidChangeNotification
UIAccessibilitySwitchControlStatusDidChangeNotification
UIAccessibilitySpeakSelectionStatusDidChangeNotification
UIAccessibilitySpeakScreenStatusDidChangeNotification
Testing
From Verifying App Accessibility on iOS, some strategies for testing Accessibility
- Debug Accessibility in iOS Simulator with the Accessibility Inspector
- Emulate the VoiceOver Experience with the Screen Curtain - or close your eyes :-)
VoiceOver Gestures
Tip: A great place to practice VoiceOver gestures is in the VoiceOver Practice area found in Settings > General > Accessibility > VoiceOver. VoiceOver needs to be enabled for the VoiceOver Practice button to appear.
Implementation Process
We need to have a way to approach this for the entire app, with the intent of being deliberate enough to not miss anything. A proposed process: (the following is just for VoiceOver at this point)
VoiceOver Review
For each screen, do a walkthrough with VoiceOver on. For every UIKit element, including container views:
- Singe-tap the element
- Note the spoken text. This should be the element label or the
accessibilityLabeltext - Controls without text or
accessibilityLabeltext should say the name of the control. i.e. “Button” - Other elements without text or
accessibilityLabelset play a short tone. - Tap and hold the element to play the
accessibilityHinttext - Note the spoken hint text
- Press and hold on any element and then slide your finger around the entire screen. Some hidden elements may trigger a sound. If we don’t want this, their
isAccessibilityElementproperty should be set toNO.
VoiceOver Design
Taking into account the findings of the Review, plan out what each element should say, and whether a hint is needed.
- Decide on the label and hint text for each UI element
- If an element should not be accessible, note that.
- If an element should be accessible that is not (a container that needs to announce itself?) note that as well.
- If a custom UI element that does not inherit from UIView needs to be accessible, note that.
- Compare and contrast with the Android implementation
VoiceOver Implementation
Question:
Many accessibility attributes can be set both programmatically and via Interface Builder. When should we prefer one versus the other? How rigorous do we need to be? Maintainability?
From the Accessibility Programming Guide for iOS
If you prefer, you can supply custom information for attributes programmatically. You might want to do this if you’re not using Interface Builder at all or if you generate your views in code instead of using Interface Builder.
As described in Make Custom Individual Views Accessible, you can set accessibility information in the implementation of your view subclass or in the code that instantiates the view. Both techniques are valid, but there is one reason why you might want to implement attribute methods in your subclass instead of setting attributes in the instantiation code: If your view displays data that is dynamic or that changes frequently, such as the time of day, you should implement the subclass methods to return fresh data as needed. For those situations, if you only set attributes when you instantiate the subclass, the returned data is likely to be out of date.
- Implement the text from the Design.
- Make elements accessible or not, as required.
- Implement code for custom containers and custom non-UIView-derived elements.
- All accessibility text is Localized. Make sure the .strings file knows this.
- For controls with variable values, make sure
accessibilityValuereturns the proper text. - For custom elements, make sure
accessibilityTraitsare set properly.
Properties to pay attention to. This list should cover 99% of cases we need to deal with.
primary
isAccessibilityElement
accessibilityLabel
accessibilityHint
accessibilityValue
accessibilityTraits
containers and custom views
accessibilityViewIsModal
accessibilityElementsHidden
shouldGroupAccessibilityChildren
accessibilityFrame