Developer notes
- Lets users enter and edit text
- A text input field cannot be automatically focused from any other component or focus cannot be automatically moved to another component. The user must control navigating to and from a text input.
- Placeholder text must meet color contrast minimum ratios
- Use a native control when at all possible vs a custom element, as it will automatically and correctly announce the role without additional development effort
- Name, Role, State must be announced when focus is on the control. Announcing the label before the input field does not meet this requirement.
- “text field” or “editbox” can be announced prior to “adjustable”, picker item or other controls.
Name
- Name describes what data is to be entered and matches a required label that is visible at all times.
- Placeholders are not considered a visible label as they disappear when data is entered.
-
Name must be announced with the role, when screen reader focus is on the text input field (Ex: “Amount due, 14.95, text field, double tap to edit”)- iOS
- iOS Options
- Set a label in Interface Builder in the Identity Inspector
- Group visible text label and the control in the same view container:
accessibilityFrameInContainerSpace
- setTitle( ) method
- Hint is used only if the results of interacting with it are not obvious from the control’s label.
- To hide labels from VoiceOver announcements, uncheck the Accessibility Enabled checkbox in the Identity Inspector
- If hiding visible label from the screen reader, use accessibilityLabel on control
- SWIFTUI: Controls can take a Text view (visible label) as part of their view builder, connecting the visible label or meaning to the control.
- Android Options
android:text
XML attribute- Optional: use
contentDescription
for a more descriptive name, depending on type of view and for elements without a visible label. contentDescription
overridesandroid:text
- Use
labelFor
attribute to associate the visible label to the control
Role
-
When not using native controls (custom controls), roles will need to be manually coded.
- iOS
- TextField
- Android
- EditBox
Groupings
-
Group text field and persistent visible text label together in one swipe.
- iOS
accessibilityFrame
accessibilityFrameInContainerSpace
- Only the container class is an accessible element
- Create a wrapper as an accessible element
- Define action upon double-tap
shouldGroupAccessibilityElement
attribute: For a precise order if the native order should be disrupted.GroupView
shouldGroupAccessibilityChildren
attribute indicates whether VoiceOver must group its children views. This allows making unique vocalizations or define a particular reading order for a part of the page- SWIFTUI:
.accessibilityElement(children)
with argument of.combine
- SWIFTUI:
.ignore
property, then add accessibility attributes and traits to stack view
- Android
- ViewGroup
- Set the container object’s
android:screenReaderFocusable
attribute to true, and each inner object’sandroid:focusable
attribute to false. In doing so, accessibility services can present the inner elements’ content descriptions/names, one after the other, in a single announcement. - JETPACK COMPOSE: Composables can be merged together using the
semantics
modifier with itsmergeDescendants
property
State
- iOS
- Active:
isEnabled property
- Disabled:
UIAccessibilityTraitNotEnabled
. Announcement: “dimmed” - AccessibilityTrait:
selected
- SWIFTUI:
.accessibility(addTraits: [.isSelected])
- Active:
- Android
- Active:
android:enabled=true
- Disabled:
android:enabled=false
. Announcement: disabled
- Active:
Focus
- Only manage focus when needed. Primarily, let the device manage default focus
- Consider how focus should be managed between child elements and their parent views
- External keyboard tab order often follows the screen reader focus, but sometimes needs focus management
- Initial focus on a screen should land in a logical place (back button, screen title, first text field, first heading)
- When a bottom navigation bar element is activated, the next screen’s initial focus should move to the top of the screen, not stay in the bottom nav bar.
-
When a menu, picker or modal is closed, the focus should return to the triggering element.
- iOS
accessibilityElementIsFocused
isAccessibilityElement
makes the element visible or not to the Accessibility APIaccessibilityElementsHidden
indicates that the children elements of the target element are visible or not to the Accessibility APIaccessibilityViewIsModal
contains the screen reader focus inside the Modal- To move screen reader focus to newly revealed content:
UIAccessibilityLayoutChangedNotification
- To NOT move focus, but dynamically announce new content:
UIAccessibilityAnnouncementNotification
UIAccessibilityContainer
protocol: Have a table of elements that defines the reading order of the elements.
- Android
importantForAccessibility
makes the element visible to the Accessibility APIandroid:focusable
android=clickable
- Implement an
onClick( )
event handler for keyboard, as well asonTouch( )
nextFocusDown
nextFocusUp
nextFocusRight
nextFocusLeft
accessibilityTraversalBefore
(or after)- To move screen reader focus to newly revealed content:
Type_View_Focused
- To NOT move focus, but dynamically announce new content:
accessibilityLiveRegion
(set to polite or assertive) - To hide controls:
importantForAccessibility=false
- For a
ViewGroup
, setscreenReaderFocusable=true
and each inner object’s attribute to keyboard focus (focusable=false
)