Sample Code

Integrating Accessibility into Your App

Make your app more accessible to users with disabilities by adding accessibility features.

Download

Overview

By adding accessibility features to your app, you make it available to a wider range of users. This sample shows how to implement accessibility for several common UI controls. The examples make the controls accessible by using accessibility properties, accessibility protocols, and the NSAccessibilityElement class.

In macOS 10.10, the Accessibility API moved to a protocol-based approach, in contrast to the key-based API from macOS 10.9 and earlier. With the protocol-based API, you can:

  • Simplify the implementation of accessibility

  • More closely align macOS accessibility features with those of iOS

  • Ensure compatibility with existing macOS apps and code

Accessibility API features in macOS versions earlier than 10.10 are deprecated, but can coexist alongside the new API. No changes are required for apps or accessibility clients that use earlier versions of the Accessibility API. If both the new and old APIs are implemented on the same class, the new API takes precedence for that class. For cell-based controls, always provide Accessibility API implementations on the cell.

Add Accessibility Attributes

Most accessibility attributes from macOS 10.9 and earlier are now properties in the following AppKit classes:

  • NSApplication

  • NSWindow

  • NSView

  • NSDrawer

  • NSPopover

  • NSCell

To set an accessibility attribute value on an instance of one of these classes (or a subclass), simply assign the value to the property:

button.setAccessibilityLabel(NSLocalizedString("My label", comment: "label to use for this button"))

Alternatively, you can override the getter in the subclass’s implementation:

override func accessibilityLabel() -> String? {
    return NSLocalizedString("Play", comment: "accessibility label of the Play button")
}

NSAccessibility contains the full list of accessibility properties.

Add Accessibility Protocols to Custom Controls

The new Accessibility API protocols define the required accessibility functions for many common accessibility elements. Conformance to an accessibility protocol is not required to use the new API, but it’s recommended when making custom controls accessible. Conforming to an accessibility protocol results in a warning for each unimplemented required function and allows the accessibilityRole and isAccessibilityElement() properties to be automatically inferred.

Standard AppKit controls conform to the related accessibility protocol (for example, NSButton conforms to the NSAccessibilityButton protocol, and NSSlider conforms to the NSAccessibilitySlider protocol). Whenever possible, subclass from the appropriate AppKit control to leverage the built-in accessibility.

To add accessibility to a custom control:

  1. Conform to the appropriate protocol.

  2. Implement all the required functions. A warning appears for each unimplemented required function.

  3. Test using VoiceOver and the Accessibility Inspector.

For example, the following example creates a custom control that subclasses NSView and draws and behaves like a button:

class CustomButtonView: NSView {

If a custom control does not conform to an accessibility protocol, you must implement the accessibilityRole and isAccessibilityElement() functions:

override func accessibilityRole() -> NSAccessibility.Role? {
    return NSAccessibility.Role.button
}

override func isAccessibilityElement() -> Bool {
    return true
}

Create an Accessibility Element

For objects that do not have a backing view (for example, a single view that draws several images, each of which should be individually accessible), create an instance of NSAccessibilityElement for each object, and return an array of the instances from the accessibility parent’s accessibilityChildren function.

Simplify Your Accessibility Code

NSAccessibilityElement has two convenience methods that simplify its use:

  • accessibilityAddChildElement(_:) — This function sets the specified element as a child of the receiver’s accessibilityChildren and the receiver as the parent to the specified element. This behavior is useful when you create hierarchies of accessibility elements.

  • accessibilityFrameInParentSpace — This property allows the accessibility element to specify its frame relative to its accessibility parent, so that the accessibilityFrame() property value (given in screen coordinates) can be automatically recalculated whenever the element or any of its parents changes location.

The new Accessibility API includes two new convenience methods in AppKit/NSAccessibility.h to simplify common accessibility tasks:

Test the Accessibility Features on Your App

The Accessibility Inspector is a tool that displays all accessibility information for the element currently under the mouse, including the accessibility hierarchy, accessibility attributes, and accessibility actions. It also shows warnings for common accessibility problems, such as a missing accessibility label. Launch the Accessibility Inspector from the Xcode > Developer Tools menu.

To test VoiceOver, you must enable it by choosing System Preferences > Accessibility > VoiceOver > Enable VoiceOver, or by pressing Command-F5. To learn how to use VoiceOver, choose System Preferences > Accessibility > VoiceOver > Open VoiceOver Training.

See Also

First Steps

protocol NSAccessibilityProtocol

The complete list of properties and methods implemented by accessible elements.

protocol NSAccessibilityContainsTransientUI

A set of methods that support accessibility in a UI that changes dynamically—usually in response to mouse-hover events.