Skip to content

Instantly share code, notes, and snippets.

@yamanoku
Last active February 22, 2020 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yamanoku/4235b22807862abc59253e5734373771 to your computer and use it in GitHub Desktop.
Save yamanoku/4235b22807862abc59253e5734373771 to your computer and use it in GitHub Desktop.
(WIP)ReactNativeのアクセシビリティ項目の日本語訳
id title description
accessibility
アクセシビリティ
AndroidとiOSで動作するように設計されたReact NativeのAPIを使って、支援技術によるアクセシブルなモバイルアプリを作成する

AndroidとiOSはどちらも、OS付属のスクリーンリーダーのVoiceOver(iOS)やTalkback(Android)などの支援技術とアプリを統合できるAPIを提供している。React Nativeには、アプリがすべてのユーザーに対応できるAPIがある。

AndroidとiOSではアプローチが少し異なるため、React Nativeの実装はプラットフォームによって異なる可能性がある。

アクセシビリティプロパティ

accessible (iOS, Android)

true の場合、ビューがアクセシビリティ要素であることを示します。ビューがアクセシビリティ要素である場合、その子は1つの選択可能なコンポーネントにグループ化されます。デフォルトでは、すべてのタッチ可能な要素はアクセシブルです。

Androidの場合, react-nativeのビューのためのaccessible={true}プロパティは、ネイティブのfocusable={true}に変換されます。

<View accessible={true}>
  <Text>text one</Text>
  <Text>text two</Text>
</View>

上の例では、'text one'と'text two'のそれぞれにアクセシビリティフォーカスを当てることはできません。その代わりに'accessible'プロパティをもつ親のビューにフォーカスを当てることはできます。

accessibilityLabel (iOS, Android)

Viewがアクセシブルとしてマークされている場合は、ViewにaccessibilityLabelを設定して、VoiceOverを使用するユーザーが選択した要素が分かるようにするのをおすすめします。ユーザーが関連する要素を選択すると、VoiceOverはこの文字列を読み取ります。

使用するには、 accessibilityLabel プロパティをView、Text、またはTouchableのカスタム文字列に設定します。

<TouchableOpacity
  accessible={true}
  accessibilityLabel="Tap me!"
  onPress={this._onPress}>
  <View style={styles.button}>
    <Text style={styles.buttonText}>Press me!</Text>
  </View>
</TouchableOpacity>

上の例では、TouchableOpacity要素のaccessibilityLabelはデフォルトで「Press me!」に設定されます。ラベルは、スペースで区切られたすべてのTextノードの子ノードを連結することによって構成されます。

accessibilityHint (iOS, Android)

アクセシビリティヒントは、アクセシビリティラベルの結果が明確でないときに、ユーザーがアクセシビリティエレメントに対してアクションを実行するとどうなるかを理解するのに役立ちます。

使用するには、 accessibilityHint プロパティをView、Text、またはTouchableのカスタム文字列に設定します。

<TouchableOpacity
  accessible={true}
  accessibilityLabel="Go back"
  accessibilityHint="Navigates to the previous screen"
  onPress={this._onPress}>
  <View style={styles.button}>
    <Text style={styles.buttonText}>Back</Text>
  </View>
</TouchableOpacity>

上の例でiOSは、デバイスのVoiceOver設定でヒントが有効になっている場合、VoiceOverはラベルの後にヒントを読み上げます。詳細はiOS デベロッパードキュメントのアクセシビリティガイドラインを読んでください。

上の例でAndroidは、Talkbackはラベルの後にヒントを読みます。現時点では、Androidでヒントをオフにすることはできません。

accessibilityIgnoresInvertColors(iOS)

画面の色を反転させるアクセシビリティ機能によって、明るさに敏感な一部のユーザーはiPhoneやiPadを見やすく、色覚異常の一部のユーザーは区別が容易になり、視力の低い一部のユーザーは見分けがつきやすくなります。ただし、写真など、反転させたくないビューがある場合もあります。この場合、このプロパティをfalseに設定して、特定のビューのカラーが反転しないようにすることができます。

accessibilityRole (iOS, Android)

accessibilityRoleは、コンポーネントの目的を支援技術ユーザに伝えるものです。

accessibilityRoleは、次のいずれかです。

  • none エレメントにroleがない場合に使用します。
  • button エレメントをボタンとして扱う場合に使用します。
  • link エレメントをリンクとして扱う場合に使用します。
  • search テキストフィールド要素を検索フィールドとして扱う場合に使用します。
  • image エレメントをイメージとして扱う場合に使用します。たとえば、ボタンやリンクと組み合わせることができます。
  • keyboardkey エレメントがキーボードキーとして機能する場合に使用します。
  • text エレメントを変更できない静的テキストとして扱う場合に使用します。
  • adjustable 要素が「調整済み」(例えばスライダー)の場合に使用します。
  • imagebutton エレメントをボタンとして扱う必要があり、イメージでもある場合に使用します。
  • header エレメントがコンテンツセクションのヘッダーとして機能する場合(例えばナビゲーションバーのタイトルなど)に使用します。
  • summary 要素を使用して、アプリケーションの初回起動時に現在の状態の簡単な要約を提供できる場合に使用します。
  • alert ユーザーに提示する重要なテキストが要素に含まれている場合に使用します。
  • checkbox 要素がチェックボックスを表す場合に使用します。チェックボックスは、オン、オフ、または混合チェック状態にすることができます。
  • combobox 要素がコンボボックスを表す場合に使用します。コンボボックスでは、複数の選択肢から選択できます。
  • menu コンポーネントが選択肢のメニューである場合に使用します。
  • menubar コンポーネントが複数のメニューのコンテナである場合に使用します。
  • menuitem メニュー内の項目を表すために使用されます。
  • progressbar タスクの進行状況を示すコンポーネントを表すために使用します。
  • radio ラジオボタンを表すために使用します。
  • radiogroup ラジオボタンのグループを表すために使用します。
  • scrollbar スクロールバーを表すために使用します。
  • spinbutton 選択項目のリストを開くボタンを表すために使用します。
  • switch オン/オフを切り替えられるスイッチを表すために使用されます。
  • tab タブを表すために使用されます。
  • tablist タブのリストを表すために使用します。
  • timer タイマーを表すために使用されます。
  • toolbar ツールバーを表すために使用されます(アクションボタンまたはコンポーネントのコンテナ)。

accessibilityState (iOS, Android)

コンポーネントの現在の状態を支援技術ユーザーに説明します。

accessibilityStateはオブジェクトです。次のフィールドがあります。

名前 説明 タイプ 必要か
disabled 要素が無効かどうかを示します。 boolean いいえ
selected 選択可能な要素が現在選択されているかどうかを示します。 boolean いいえ
checked チェック可能な要素の状態を示します。このフィールドには、booleanまたは「混合の」文字列を入力して、チェックボックスの組み合わせを表すことができます。 boolean か 「混合」 いいえ
busy 要素が現在ビジー状態かどうかを示します。 boolean いいえ
expanded 展開可能な要素が現在展開されているか折りたたまれているかを示します。 boolean いいえ

使用するには、特定の定義を持つオブジェクトにaccessibilityStateを設定します。

accessibilityValue (iOS, Android)

コンポーネントの現在の値を表します。コンポーネントの値のテキストによる説明、またはスライダーやステータスバーなどの範囲ベースのコンポーネントの場合は範囲の情報(最小、現在、最大)が含まれます。

accessibilityValue はオブジェクトです。次のフィールドがあります。

名前 説明 タイプ 必要か
min コンポーネント範囲の最小値 整数値 nowがセットされている場合必要
max コンポーネント範囲の最大値 整数値 nowがセットされている場合必要
now コンポーネント範囲の現在値 整数値 いいえ
text コンポーネントの値の説明。minnowmax設定されている場合、上書きします。
文字列 いいえ

accessibilityViewIsModal (iOS)

VoiceOverがレシーバー側の兄弟要素であるビュー内の要素を無視するかどうかを示すブール値。

For example, in a window that contains sibling views A and B, setting accessibilityViewIsModal to true on view B causes VoiceOver to ignore the elements in the view A. On the other hand, if view B contains a child view C and you set accessibilityViewIsModal to true on view C, VoiceOver does not ignore the elements in view A.

たとえば、兄弟要素のビュー AB を含むウィンドウで、ビュー BaccessibilityViewIsModuletrue に設定すると、VoiceOverはビュー A 要素を無視します。一方、ビュー B に子ビュー C が含まれ、ビュー CaccessibilityViewIsModuletrue に設定した場合、VoiceOverはビュー A 要素を無視しません。

accessibilityElementsHidden (iOS)

アクセシビリティ要素に含まれるアクセシビリティ要素を非表示にするかどうかを示すブール値。

For example, in a window that contains sibling views A and B, setting accessibilityElementsHidden to true on view B causes VoiceOver to ignore the elements in the view B. This is similar to the Android property importantForAccessibility="no-hide-descendants".

たとえば、兄弟要素のビュー AB を含むウィンドウで、ビュー BaccessibilityElementsHiddentrue に設定すると、VoiceOverはビュー B のエレメントを無視します。これはAndroidのプロパティ importantForAccessibility="no-hide-descendants" に似ています。

onAccessibilityTap (iOS, Android)

このプロパティを使用して、ユーザーがアクセシブルな要素を選択中にその要素をダブルタップしてアクティブにしたときに呼び出されるカスタム関数を割り当てます。

onMagicTap (iOS)

このプロパティは、ユーザーが二本指でダブルタップする「マジックタップ」ジェスチャを実行したときに呼び出されるカスタム関数に割り当てます。マジックタップ機能は、ユーザーがコンポーネントに対して実行できる最も関連性の高いアクションを実行する必要があります。iPhoneの電話アプリでは、マジックタップが電話に出たり、電話を終了したりします。選択した要素に onMagicTap 機能がない場合は、機能するビューが見つかるまで、ビュー階層が上に移動します。

onAccessibilityEscape (iOS)

このプロパティは、なにかをエスケープするジェスチャ、つまり二本指でZ型のジェスチャを実行したときに呼び出されるカスタム関数に割り当てます。エスケープ機能は、ユーザインタフェース内で階層的に戻る必要があります。これは、ナビゲーション階層を上下に移動したり、モーダルユーザインタフェースを削除することを意味します。選択した要素に onAccessibilityEscape 関数がない場合、システムはビュー階層の上に移動して、ビューが見つからなかったことを示すビューを見つけるか、そのビューが見つからなかったことを示すエラーを見つけます。

accessibilityLiveRegion (Android)

When components dynamically change, we want TalkBack to alert the end user. This is made possible by the ‘accessibilityLiveRegion’ property. It can be set to ‘none’, ‘polite’ and ‘assertive’:

  • none Accessibility services should not announce changes to this view.
  • polite Accessibility services should announce changes to this view.
  • assertive Accessibility services should interrupt ongoing speech to immediately announce changes to this view.
<TouchableWithoutFeedback onPress={this._addOne}>
  <View style={styles.embedded}>
    <Text>Click me</Text>
  </View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
  Clicked {this.state.count} times
</Text>

In the above example method _addOne changes the state.count variable. As soon as an end user clicks the TouchableWithoutFeedback, TalkBack reads text in the Text view because of its 'accessibilityLiveRegion=”polite”' property.

importantForAccessibility (Android)

In the case of two overlapping UI components with the same parent, default accessibility focus can have unpredictable behavior. The ‘importantForAccessibility’ property will resolve this by controlling if a view fires accessibility events and if it is reported to accessibility services. It can be set to ‘auto’, ‘yes’, ‘no’ and ‘no-hide-descendants’ (the last value will force accessibility services to ignore the component and all of its children).

<View style={styles.container}>
  <View style={{position: 'absolute', left: 10, top: 10, right: 10, height: 100,
    backgroundColor: 'green'}} importantForAccessibility=”yes”>
    <Text> First layout </Text>
  </View>
  <View style={{position: 'absolute', left: 10, top: 10, right: 10, height: 100,
    backgroundColor: 'yellow'}} importantForAccessibility=”no-hide-descendants>
    <Text> Second layout </Text>
  </View>
</View>

In the above example, the yellow layout and its descendants are completely invisible to TalkBack and all other accessibility services. So we can use overlapping views with the same parent without confusing TalkBack.

Accessibility Actions

Accessibility actions allow an assistive technology to programmatically invoke the actions of a component. In order to support accessibility actions, a component must do two things:

  • Define the list of actions it supports via the accessibilityActions property.
  • Implement an onAccessibilityAction function to handle action requests.

The accessibilityActions property should contain a list of action objects. Each action object should contain the following fields:

Name Type Required
name string Yes
label string No

Actions either represent standard actions, such as clicking a button or adjusting a slider, or custom actions specific to a given component such as deleting an email message. The name field is required for both standard and custom actions, but label is optional for standard actions.

When adding support for standard actions, name must be one of the following:

  • 'magicTap' - iOS only - While VoiceOver focus is on or inside the component, the user double tapped with two fingers.
  • 'escape' - iOS only - While VoiceOver focus is on or inside the component, the user performed a two finger scrub gesture (left, right, left).
  • 'activate' - Activate the component. Typically this should perform the same action as when the user touches or clicks the component when not using an assistive technology. This is generated when a screen reader user double taps the component.
  • 'increment' - Increment an adjustable component. On iOS, VoiceOver generates this action when the component has a role of 'adjustable' and the user places focus on it and swipes upward. On Android, TalkBack generates this action when the user places accessibility focus on the component and presses the volume up button.
  • 'decrement' - Decrement an adjustable component. On iOS, VoiceOver generates this action when the component has a role of 'adjustable' and the user places focus on it and swipes downward. On Android, TalkBack generates this action when the user places accessibility focus on the component and presses the volume down button.
  • 'longpress' - Android only - This action is generated when the user places accessibility focus on the component and double tap and holds one finger on the screen. Typically, this should perform the same action as when the user holds down one finger on the component while not using an assistive technology.

The label field is optional for standard actions, and is often unused by assistive technologies. For custom actions, it is a localized string containing a description of the action to be presented to the user.

To handle action requests, a component must implement an onAccessibilityAction function. The only argument to this function is an event containing the name of the action to perform. The below example from RNTester shows how to create a component which defines and handles several custom actions.

<View
  accessible={true}
  accessibilityActions={[
    {name: 'cut', label: 'cut'},
    {name: 'copy', label: 'copy'},
    {name: 'paste', label: 'paste'},
  ]}
  onAccessibilityAction={(event) => {
    switch (event.nativeEvent.actionName) {
      case 'cut':
        Alert.alert('Alert', 'cut action success');
        break;
      case 'copy':
        Alert.alert('Alert', 'copy action success');
        break;
      case 'paste':
        Alert.alert('Alert', 'paste action success');
        break;
    }
  }}
/>

Checking if a Screen Reader is Enabled

The AccessibilityInfo API allows you to determine whether or not a screen reader is currently active. See the AccessibilityInfo documentation for details.

Sending Accessibility Events (Android)

Sometimes it is useful to trigger an accessibility event on a UI component (i.e. when a custom view appears on a screen or set accessibility focus to a view). Native UIManager module exposes a method ‘sendAccessibilityEvent’ for this purpose. It takes two arguments: view tag and a type of an event. The supported event types are typeWindowStateChanged, typeViewFocused and typeViewClicked.

import { Platform, UIManager, findNodeHandle } from 'react-native';

if (Platform.OS === 'android') {
    UIManager.sendAccessibilityEvent(
      findNodeHandle(this),
      UIManager.AccessibilityEventTypes.typeViewFocused);
  }
}

Testing VoiceOver Support (iOS)

To enable VoiceOver, go to the Settings app on your iOS device (it's not available for simulator). Tap General, then Accessibility. There you will find many tools that people use to make their devices more usable, such as bolder text, increased contrast, and VoiceOver.

To enable VoiceOver, tap on VoiceOver under "Vision" and toggle the switch that appears at the top.

At the very bottom of the Accessibility settings, there is an "Accessibility Shortcut". You can use this to toggle VoiceOver by triple clicking the Home button.

Testing TalkBack Support (Android)

To enable TalkBack, go to the Settings app on your Android device or emulator. Tap Accessibility, then TalkBack. Toggle the "Use service" switch to enable or disable it.

P.S. Android emulator doesn’t have TalkBack by default. To install it:

  1. Download TalkBack file here: https://google-talkback.en.uptodown.com/android
  2. Drag the downloaded .apk file into the emulator

You can use the volume key shortcut to toggle TalkBack. To turn on the volume key shortcut, go to the Settings app, then Accessibility. At the top, turn on Volume key shortcut.

To use the volume key shortcut, press both volume keys for 3 seconds to start an accessibility tool.

Additionally, if you prefer, you can toggle TalkBack via command line with:

# disable
adb shell settings put secure enabled_accessibility_services com.android.talkback/com.google.android.marvin.talkback.TalkBackService

# enable
adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService

Additional Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment