This is a guest post by Dimitar Topuzov, QA Architect on the NativeScript Team
A well-designed user interface (UI) often has elements that don't require an explicit label to indicate their purpose to the user. A checkbox next to an item in a task list application has a fairly obvious purpose, as does a trash can in a file manager application. However, to your users with vision impairment, other UI cues are needed. Fortunately, both iOS and Android provide APIs for making apps accessible to people with disabilities. Moreover, both platforms provide tools and technologies (like TalkBack and VoiceOver) that can make the lives of the visually impaired easier.
The NativeScript framework produces native apps. Thus, all vendor tools for impaired users work right out of the box. Also, all popular automation tools and frameworks that are based on native Android and iOS accessibility models (like Appium) also just work, with no additional bridging code or programming required. In addition to the entire set of native accessibility capabilities, NativeScript also provides cross-platform APIs designed to assist developers with making more accessible apps.
Let's examine the automationText property that can be set on a view:
<
GridLayout
width
=
"290"
automationText
=
"MyGrid"
/>
On Android, this property will set android:contentDescription attribute on specified element, which will help Android accessibility tools and services to work properly. On iOS this will set accessibilityIdentifier which is used to uniquely identify an element in the scripts you write using the UI Automation interfaces.
The automationText property can also be used with binding in more complex scenarios. Take a look at the following example from the NativeScript Examples app: Google PlayApp StoreSource
<
Repeater.itemTemplate
>
<
StackLayout
touch
=
"tileTouch"
tap
=
"navigateToExample"
cssClass
=
"example-item"
automationText
=
"{{ title }}"
orientation
=
"{{ $parents['Repeater'].useListLayout, $parents['Repeater'].useListLayout ? 'horizontal' : 'vertical' }}"
visibility
=
"{{ $parents['Repeater'].showOnlyNew, (!$parents['Repeater'].showOnlyNew || isNew) ? 'visible' : 'collapsed' }}"
>
<
GridLayout
horizontalAlignment
=
"center"
columns
=
"*"
rows
=
"*"
cssClass
=
"{{ $parents['Repeater'].useListLayout, $parents['Repeater'].useListLayout ? 'example-img-list' : 'example-img-wrap' }}"
>
<
Image
src
=
"{{ image }}"
cssClass
=
"{{ isNew ? 'list-example-image-new' : 'list-example-image' }}"
borderColor
=
"{{ $parents['Repeater'].group.tint }}"
stretch
=
"aspectFit"
/>
<
Image
src
=
"{{ $parents['Page'].group.id, 'res://ic_new_' + $parents['Repeater'].group.id }}"
cssClass
=
"new"
visibility
=
"{{ isNew ? 'visible' : 'collapsed' }}"
stretch
=
"none"
/>
</
GridLayout
>
<
StackLayout
>
<
Label
text
=
"{{ title }}"
cssClass
=
"{{ $parents['Repeater'].useListLayout, $parents['Repeater'].useListLayout ? 'example-title-list' : 'example-title-wrap' }}"
/>
<
Label
text
=
"{{ controls }}"
textWrap
=
"true"
cssClass
=
"{{ $parents['Repeater'].useListLayout, $parents['Repeater'].useListLayout ? 'used-controls-list' : 'used-controls-wrap' }}"
/>
</
StackLayout
>
</
StackLayout
>
</
Repeater.itemTemplate
>
Keep in mind, NativeScript always gives you full access to all native APIs so you can have full control of native accessibility features.
For example:
var
signOutButton = page.getViewById(
"signOutLabel"
);
signOutButton.android.setClickable(
true
);
Many governments and organizations worldwide mandate apps have accessibility features for impaired users. It is important to us to provide you with all native accessibility features out of the box and also the very best in cross-platform abstractions so you can build and deploy a successful app for all users, regardless of physical abilities.