無障礙功能
Android 和 iOS 都提供 API,用於將應用程式與輔助技術整合,例如內建的螢幕閱讀器 VoiceOver (iOS) 和 TalkBack (Android)。React Native 具有互補的 API,可讓您的應用程式容納所有使用者。
Android 和 iOS 在方法上略有不同,因此 React Native 的實作可能會因平台而異。
無障礙功能屬性
accessible
當 true
時,表示視圖是無障礙元素。當視圖是無障礙元素時,它會將其子元素組合成單個可選組件。預設情況下,所有可觸控元素都是無障礙的。
在 Android 上,react-native View 的 accessible={true}
屬性將轉換為原生 focusable={true}
。
<View accessible={true}>
<Text>text one</Text>
<Text>text two</Text>
</View>
在上面的範例中,無障礙功能焦點僅在具有 accessible
屬性的父視圖上可用,而對於「文字一」和「文字二」則不可單獨使用。
accessibilityLabel
當視圖標記為無障礙時,最好在視圖上設定 accessibilityLabel
,以便使用 VoiceOver 或 TalkBack 的人知道他們選擇了哪個元素。當選取關聯的元素時,螢幕閱讀器將口頭表達此字串。
若要使用,請在您的 View、Text 或 Touchable 上將 accessibilityLabel
屬性設定為自訂字串
<TouchableOpacity
accessible={true}
accessibilityLabel="Tap me!"
onPress={onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
在上面的範例中,TouchableOpacity 元素上的 accessibilityLabel
將預設為「Press me!」。標籤是透過串連所有以空格分隔的 Text 節點子元素來建構的。
accessibilityLabelledBy
Android
對另一個元素 nativeID 的參考,用於建構複雜的表單。accessibilityLabelledBy
的值應與相關元素的 nativeID
相符
<View>
<Text nativeID="formLabel">Label for Input Field</Text>
<TextInput
accessibilityLabel="input"
accessibilityLabelledBy="formLabel"
/>
</View>
在上面的範例中,當焦點放在 TextInput 上時,螢幕閱讀器會宣告 Input, Edit Box for Label for Input Field
。
accessibilityHint
當無法從無障礙功能標籤本身清楚得知動作的結果時,可以使用無障礙功能提示向使用者提供額外的背景資訊。
在您的 View、Text 或 Touchable 上提供 accessibilityHint
屬性自訂字串
<TouchableOpacity
accessible={true}
accessibilityLabel="Go back"
accessibilityHint="Navigates to the previous screen"
onPress={onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Back</Text>
</View>
</TouchableOpacity>
在上面的範例中,如果使用者在其裝置的 VoiceOver 設定中啟用了提示,VoiceOver 將在標籤之後讀取提示。在 iOS 開發人員文件中閱讀更多關於 accessibilityHint
指南的資訊
在上面的範例中,TalkBack 將在標籤之後讀取提示。目前,提示無法在 Android 上關閉。
accessibilityLanguage
iOS
透過使用 accessibilityLanguage
屬性,螢幕閱讀器將了解在閱讀元素的標籤、值和提示時要使用的語言。提供的字串值必須遵循 BCP 47 規範。
<View
accessible={true}
accessibilityLabel="Pizza"
accessibilityLanguage="it-IT">
<Text>🍕</Text>
</View>
accessibilityIgnoresInvertColors
iOS
反轉螢幕色彩是 iOS 和 iPadOS 中提供的一項無障礙功能,適用於患有色盲、低視力或視力障礙的人。如果當此設定開啟時,您有不想反轉的視圖(可能是照片),請將此屬性設定為 true
。
accessibilityLiveRegion
Android
當組件動態變更時,我們希望 TalkBack 提醒終端使用者。這可以透過 accessibilityLiveRegion
屬性來實現。它可以設定為 none
、polite
和 assertive
- none 無障礙服務不應宣告此視圖的變更。
- polite 無障礙服務應宣告此視圖的變更。
- assertive 無障礙服務應中斷正在進行的語音,以立即宣告此視圖的變更。
<TouchableWithoutFeedback onPress={addOne}>
<View style={styles.embedded}>
<Text>Click me</Text>
</View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
Clicked {count} times
</Text>
在上面的範例方法中,addOne
會變更狀態變數 count
。當 TouchableWithoutFeedback 被觸發時,TalkBack 會讀取 Text 視圖中的文字,因為其 accessibilityLiveRegion="polite"
屬性。
accessibilityRole
accessibilityRole
向輔助技術使用者傳達組件的用途。
accessibilityRole
可以是下列其中一項
- adjustable 當元素可以「調整」時使用(例如滑桿)。
- alert 當元素包含要呈現給使用者的重要文字時使用。
- button 當元素應視為按鈕時使用。
- checkbox 當元素代表可以選取、取消選取或具有混合選取狀態的核取方塊時使用。
- combobox 當元素代表組合方塊時使用,組合方塊允許使用者在多個選項之間進行選取。
- header 當元素充當內容區段的標頭時使用(例如導覽列的標題)。
- image 當元素應視為影像時使用。可以與按鈕或連結組合。
- imagebutton 當元素應視為按鈕並且也是影像時使用。
- keyboardkey 當元素充當鍵盤按鍵時使用。
- link 當元素應視為連結時使用。
- menu 當組件是選項選單時使用。
- menubar 當組件是多個選單的容器時使用。
- menuitem 用於表示選單中的項目。
- none 當元素沒有角色時使用。
- progressbar 用於表示指示任務進度的組件。
- radio 用於表示單選按鈕。
- radiogroup 用於表示單選按鈕群組。
- scrollbar 用於表示捲軸。
- search 當文字欄位元素也應視為搜尋欄位時使用。
- spinbutton 用於表示開啟選項清單的按鈕。
- summary 當元素可用於在應用程式首次啟動時提供應用程式中目前狀況的快速摘要時使用。
- switch 用於表示可以開啟和關閉的開關。
- tab 用於表示索引標籤。
- tablist 用於表示索引標籤清單。
- text 當元素應視為無法變更的靜態文字時使用。
- timer 用於表示計時器。
- togglebutton 用於表示切換按鈕。應與 accessibilityState checked 一起使用,以指示按鈕是否已切換為開啟或關閉。
- toolbar 用於表示工具列(動作按鈕或組件的容器)。
- grid 與 ScrollView、VirtualizedList、FlatList 或 SectionList 一起使用以表示網格。將網格的進入/退出宣告新增至 Android 的 GridView。
accessibilityShowsLargeContentViewer
iOS
一個布林值,用於決定當使用者長按元素時是否顯示大型內容檢視器。
在 iOS 13.0 及更高版本中可用。
accessibilityLargeContentTitle
iOS
一個字串,將在顯示大型內容檢視器時用作其標題。
需要將 accessibilityShowsLargeContentViewer
設定為 true
。
<View
accessibilityShowsLargeContentViewer={true}
accessibilityLargeContentTitle="Home Tab">
<Text>Home</Text>
</View>
accessibilityState
向輔助技術使用者描述組件的目前狀態。
accessibilityState
是一個物件。它包含以下欄位
名稱 | 描述 | 類型 | 必要 |
---|---|---|---|
disabled | 指示元素是否已停用。 | 布林值 | 否 |
selected | 指示可選取元素目前是否已選取。 | 布林值 | 否 |
checked | 指示可勾選元素的狀態。此欄位可以採用布林值或「mixed」字串來表示混合核取方塊。 | 布林值或 'mixed' | 否 |
busy | 指示元素目前是否忙碌。 | 布林值 | 否 |
expanded | 指示可展開元素目前是展開還是摺疊。 | 布林值 | 否 |
若要使用,請將 accessibilityState
設定為具有特定定義的物件。
accessibilityValue
表示組件的目前值。它可以是組件值的文字描述,或者對於基於範圍的組件(例如滑桿和進度列),它包含範圍資訊(最小值、目前值和最大值)。
accessibilityValue
是一個物件。它包含以下欄位
名稱 | 描述 | 類型 | 必要 |
---|---|---|---|
min | 此組件範圍的最小值。 | 整數 | 如果設定了 now ,則為必要項。 |
max | 此組件範圍的最大值。 | 整數 | 如果設定了 now ,則為必要項。 |
now | 此組件範圍的目前值。 | 整數 | 否 |
text | 此組件值的文字描述。如果設定了,將覆寫 min 、now 和 max 。 | 字串 | 否 |
accessibilityViewIsModal
iOS
一個布林值,指示 VoiceOver 是否應忽略接收器同層級視圖中的元素。
例如,在包含同層級視圖 A
和 B
的視窗中,在視圖 B
上將 accessibilityViewIsModal
設定為 true
會導致 VoiceOver 忽略視圖 A
中的元素。另一方面,如果視圖 B
包含子視圖 C
,並且您在視圖 C
上將 accessibilityViewIsModal
設定為 true
,則 VoiceOver 不會忽略視圖 A
中的元素。
accessibilityElementsHidden
iOS
一個布林值,指示此無障礙元素中包含的無障礙元素是否已隱藏。
例如,在包含同層級視圖 A
和 B
的視窗中,在視圖 B
上將 accessibilityElementsHidden
設定為 true
會導致 VoiceOver 忽略視圖 B
中的元素。這類似於 Android 屬性 importantForAccessibility="no-hide-descendants"
。
aria-valuemax
表示基於範圍的組件(例如滑桿和進度列)的最大值。
aria-valuemin
表示基於範圍的組件(例如滑桿和進度列)的最小值。
aria-valuenow
表示基於範圍的組件(例如滑桿和進度列)的目前值。
aria-valuetext
表示組件的文字描述。
aria-busy
指示元素正在修改,且輔助技術可能希望等到變更完成後再告知使用者更新。
類型 | 預設值 |
---|---|
布林值 | false |
aria-checked
指示可勾選元素的狀態。此欄位可以採用布林值或「mixed」字串來表示混合核取方塊。
類型 | 預設值 |
---|---|
布林值、「mixed」 | false |
aria-disabled
指示元素是可感知的但已停用,因此無法編輯或以其他方式操作。
類型 | 預設值 |
---|---|
布林值 | false |
aria-expanded
指示可展開元素目前是展開還是摺疊。
類型 | 預設值 |
---|---|
布林值 | false |
aria-hidden
指示此無障礙元素中包含的無障礙元素是否已隱藏。
例如,在包含同層級視圖 A
和 B
的視窗中,在視圖 B
上將 aria-hidden
設定為 true
會導致 VoiceOver 忽略視圖 B
中的元素。
類型 | 預設值 |
---|---|
布林值 | false |
aria-label
定義標記互動式元素的字串值。
類型 |
---|
字串 |
aria-labelledby
Android
識別標記其所套用元素的元素。aria-labelledby
的值應與相關元素的 nativeID
相符
<View>
<Text nativeID="formLabel">Label for Input Field</Text>
<TextInput aria-label="input" aria-labelledby="formLabel" />
</View>
類型 |
---|
字串 |
aria-live
Android
指示元素將被更新,並描述使用者代理程式、輔助技術和使用者可以從即時區域期望的更新類型。
- off 無障礙服務不應宣告此視圖的變更。
- polite 無障礙服務應宣告此視圖的變更。
- assertive 無障礙服務應中斷正在進行的語音,以立即宣告此視圖的變更。
類型 | 預設值 |
---|---|
enum('assertive' , 'off' , 'polite' ) | 'off' |
aria-modal
iOS
布林值,指示 VoiceOver 是否應忽略接收器同層級視圖中的元素。
類型 | 預設值 |
---|---|
布林值 | false |
aria-selected
指示可選取元素目前是否已選取。
類型 |
---|
布林值 |
importantForAccessibility
Android
在具有相同父元素的兩個重疊 UI 組件的情況下,預設無障礙功能焦點可能會產生無法預測的行為。importantForAccessibility
屬性將透過控制視圖是否觸發無障礙功能事件以及是否向無障礙功能服務報告來解決此問題。它可以設定為 auto
、yes
、no
和 no-hide-descendants
(最後一個值將強制無障礙功能服務忽略組件及其所有子元素)。
<View style={styles.container}>
<View
style={[styles.layout, {backgroundColor: 'green'}]}
importantForAccessibility="yes">
<Text>First layout</Text>
</View>
<View
style={[styles.layout, {backgroundColor: 'yellow'}]}
importantForAccessibility="no-hide-descendants">
<Text>Second layout</Text>
</View>
</View>
在上面的範例中,yellow
佈局及其子元素對於 TalkBack 和所有其他無障礙功能服務完全不可見。因此,我們可以使用具有相同父元素的重疊視圖,而不會混淆 TalkBack。
onAccessibilityEscape
iOS
將此屬性指派給自訂函數,當有人執行「escape」手勢(即兩指 Z 形手勢)時,將會呼叫該函數。escape 函數應在使用者介面中以階層方式後退。這可能表示在導覽階層中向上或向後移動,或關閉強制回應使用者介面。如果選取的元素沒有 onAccessibilityEscape
函數,系統將嘗試向上遍歷視圖階層,直到找到一個有該函數的視圖,否則會發出 bonk 聲,表示無法找到。
onAccessibilityTap
iOS
使用此屬性指派自訂函數,以便在有人透過在選取可存取元素時點擊兩下來啟動該元素時呼叫該函數。
onMagicTap
iOS
將此屬性指派給自訂函數,當有人執行「magic tap」手勢(即兩指點擊兩下)時,將會呼叫該函數。magic tap 函數應執行使用者可以在組件上執行的最相關動作。在 iPhone 上的「電話」應用程式中,magic tap 會接聽電話或結束目前通話。如果選取的元素沒有 onMagicTap
函數,系統將遍歷視圖階層,直到找到一個有該函數的視圖。
role
role
傳達組件的用途,並且優先於 accessibilityRole
屬性。
role
可以是下列其中一項
- alert 當元素包含要呈現給使用者的重要文字時使用。
- button 當元素應視為按鈕時使用。
- checkbox 當元素代表可以選取、取消選取或具有混合選取狀態的核取方塊時使用。
- combobox 當元素代表組合方塊時使用,組合方塊允許使用者在多個選項之間進行選取。
- grid 與 ScrollView、VirtualizedList、FlatList 或 SectionList 一起使用以表示網格。將網格的進入/退出宣告新增至 android GridView。
- heading 當元素充當內容區段的標頭時使用(例如導覽列的標題)。
- img 當元素應視為影像時使用。例如,可以與按鈕或連結組合。
- link 當元素應視為連結時使用。
- list 用於識別項目清單。
- listitem 用於識別清單中的項目。
- menu 當組件是選項選單時使用。
- menubar 當組件是多個選單的容器時使用。
- menuitem 用於表示選單中的項目。
- none 當元素沒有角色時使用。
- presentation 當元素沒有角色時使用。
- progressbar 用於表示指示任務進度的組件。
- radio 用於表示單選按鈕。
- radiogroup 用於表示單選按鈕群組。
- scrollbar 用於表示捲軸。
- searchbox 當文字欄位元素也應視為搜尋欄位時使用。
- slider 當元素可以「調整」時使用(例如滑桿)。
- spinbutton 用於表示開啟選項清單的按鈕。
- summary 當元素可用於在應用程式首次啟動時提供應用程式中目前狀況的快速摘要時使用。
- switch 用於表示可以開啟和關閉的開關。
- tab 用於表示索引標籤。
- tablist 用於表示索引標籤清單。
- timer 用於表示計時器。
- toolbar 用於表示工具列(動作按鈕或組件的容器)。
無障礙功能動作
無障礙功能動作允許輔助技術以程式設計方式調用組件的動作。為了支援無障礙功能動作,組件必須執行兩件事
- 透過
accessibilityActions
屬性定義其支援的動作清單。 - 實作
onAccessibilityAction
函數以處理動作請求。
accessibilityActions
屬性應包含動作物件的清單。每個動作物件應包含以下欄位
名稱 | 類型 | 必要 |
---|---|---|
name | 字串 | 是 |
label | 字串 | 否 |
動作可以表示標準動作(例如點擊按鈕或調整滑桿),或特定於給定組件的自訂動作(例如刪除電子郵件訊息)。name
欄位對於標準動作和自訂動作都是必要的,但 label
對於標準動作是選用的。
在新增對標準動作的支援時,name
必須是下列其中一項
'magicTap'
- 僅限 iOS - 當 VoiceOver 焦點在組件上或組件內時,使用者以兩根手指點擊兩下。'escape'
- 僅限 iOS - 當 VoiceOver 焦點在組件上或組件內時,使用者執行兩指擦洗手勢(左、右、左)。'activate'
- 啟動組件。這應執行相同的動作,無論是否使用輔助技術。當螢幕閱讀器使用者點擊兩下組件時,即會參與。'increment'
- 遞增可調整組件。在 iOS 上,當組件的角色為'adjustable'
且使用者將焦點放在其上並向上滑動時,VoiceOver 會產生此動作。在 Android 上,當使用者將無障礙功能焦點放在組件上並按下音量調高按鈕時,TalkBack 會產生此動作。'decrement'
- 遞減可調整組件。在 iOS 上,當組件的角色為'adjustable'
且使用者將焦點放在其上並向下滑動時,VoiceOver 會產生此動作。在 Android 上,當使用者將無障礙功能焦點放在組件上並按下音量調低按鈕時,TalkBack 會產生此動作。'longpress'
- 僅限 Android - 當使用者將無障礙功能焦點放在組件上,然後點擊兩下並將一根手指按住螢幕時,會產生此動作。這應執行相同的動作,無論是否使用輔助技術。
label
欄位對於標準動作是選用的,並且通常不被輔助技術使用。對於自訂動作,它是包含要呈現給使用者的動作描述的本地化字串。
為了處理動作請求,組件必須實作 onAccessibilityAction
函數。此函數的唯一引數是包含要執行動作名稱的事件。以下來自 RNTester 的範例示範如何建立定義和處理多個自訂動作的組件。
<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;
}
}}
/>
檢查螢幕閱讀器是否已啟用
AccessibilityInfo
API 允許您判斷螢幕閱讀器目前是否處於活動狀態。請參閱 AccessibilityInfo 文件以取得詳細資訊。
傳送無障礙功能事件Android
有時,在 UI 組件上觸發無障礙功能事件很有用(即,當自訂視圖出現在螢幕上或將無障礙功能焦點設定為視圖時)。原生 UIManager 模組公開了一種方法 ‘sendAccessibilityEvent’ 用於此目的。它接受兩個引數:視圖標籤和事件類型。支援的事件類型為 typeWindowStateChanged
、typeViewFocused
和 typeViewClicked
。
import {Platform, UIManager, findNodeHandle} from 'react-native';
if (Platform.OS === 'android') {
UIManager.sendAccessibilityEvent(
findNodeHandle(this),
UIManager.AccessibilityEventTypes.typeViewFocused,
);
}
測試 TalkBack 支援Android
若要啟用 TalkBack,請前往 Android 裝置或模擬器上的「設定」應用程式。點擊「無障礙功能」,然後點擊「TalkBack」。切換「使用服務」開關以啟用或停用它。
Android 模擬器預設未安裝 TalkBack。您可以透過 Google Play 商店在模擬器上安裝 TalkBack。請務必選擇已安裝 Google Play 商店的模擬器。這些模擬器可在 Android Studio 中取得。
您可以使用音量鍵快捷鍵來切換 TalkBack。若要開啟音量鍵快捷鍵,請前往「設定」應用程式,然後點擊「無障礙功能」。在頂端,開啟音量鍵快捷鍵。
若要使用音量鍵快捷鍵,請同時按下兩個音量鍵 3 秒鐘以啟動無障礙功能工具。
此外,如果您願意,您也可以透過命令列切換 TalkBack
# 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
測試 VoiceOver 支援iOS
若要在您的 iOS 或 iPadOS 裝置上啟用 VoiceOver,請前往「設定」應用程式,點擊「一般」,然後點擊「無障礙功能」。您將在那裡找到許多工具,供人們啟用其裝置以使其更易於使用,包括 VoiceOver。若要啟用 VoiceOver,請點擊「視覺」下的「VoiceOver」,然後切換頂端出現的開關。
在「無障礙功能」設定的最底部,有一個「無障礙功能快捷鍵」。您可以使用它透過按三下 Home 鍵來切換 VoiceOver。
VoiceOver 無法透過模擬器使用,但您可以使用 Xcode 的「無障礙功能檢查器」透過應用程式使用 macOS VoiceOver。請注意,最好始終使用裝置進行測試,因為 macOS 的 VoiceOver 可能會導致不同的體驗。