跳到主要內容

無障礙 API 更新

·7 分鐘閱讀
Ziqi Chen
加州大學柏克萊分校學生

動機

隨著科技進步,行動應用程式在日常生活中變得越來越重要,建立無障礙應用程式的必要性也日益重要。

React Native 有限的無障礙 API 一直是開發人員的一大痛點,因此我們對無障礙 API 進行了一些更新,使其更容易建立具包容性的行動應用程式。

現有 API 的問題

問題一:兩個完全不同但相似的屬性 - accessibilityComponentType (Android) 和 accessibilityTraits (iOS)

accessibilityComponentTypeaccessibilityTraits 是兩個屬性,用於告知 Android 上的 TalkBack 和 iOS 上的 VoiceOver 使用者正在與哪種 UI 元素互動。這兩個屬性最大的問題在於

  1. 它們是兩個不同的屬性,使用方法不同,但目的相同。 在先前的 API 中,這些是兩個不同的屬性(每個平台一個),這不僅不方便,而且也讓許多開發人員感到困惑。iOS 上的 accessibilityTraits 允許 17 個不同的值,而 Android 上的 accessibilityComponentType 僅允許 4 個值。此外,這些值在很大程度上沒有重疊。即使這兩個屬性的輸入類型也不同。accessibilityTraits 允許傳入特徵陣列或單一特徵,而 accessibilityComponentType 僅允許單一值。
  2. Android 上的功能非常有限。 使用舊的屬性,Talkback 能夠識別的 UI 元素只有「button」、「radiobutton_checked」和「radiobutton_unchecked」。

問題二:不存在的無障礙提示:

無障礙提示可協助使用 TalkBack 或 VoiceOver 的使用者了解當他們對無障礙元素執行操作時會發生什麼,而這並非僅透過無障礙標籤顯而易見。這些提示可以在設定面板中開啟和關閉。先前,React Native 的 API 完全不支援無障礙提示。

問題三:忽略反轉顏色:

一些有視力障礙的使用者會在他們的手機上使用反轉顏色,以獲得更高的螢幕對比度。Apple 為 iOS 提供了一個 API,允許開發人員忽略某些視圖。這樣一來,當使用者開啟反轉顏色設定時,影像和視訊就不會失真。React Native 目前不支援此 API。

新 API 的設計

解決方案一:合併 accessibilityComponentType (Android) 和 accessibilityTraits (iOS)

為了消除 accessibilityComponentTypeaccessibilityTraits 之間的混淆,我們決定將它們合併為單一屬性。這很有道理,因為它們在技術上具有相同的預期功能,並且透過合併它們,開發人員在建置無障礙功能時不再需要擔心平台特定的複雜性。

背景

在 iOS 上,UIAccessibilityTraits 是一個可以設定在任何 NSObject 上的屬性。透過 javascript 屬性傳遞到原生的 17 個特徵中的每一個都對應到 Objective-C 中的 UIAccessibilityTraits 元素。特徵各自以長整數表示,並且每個設定的特徵都會進行 OR 運算。

然而,在 Android 上,AccessibilityComponentType 是 React Native 創造的概念,並且不直接對應到 Android 中的任何屬性。無障礙功能由無障礙委派處理。每個視圖都有預設的無障礙委派。如果您想要自訂任何無障礙操作,您必須建立新的無障礙委派,覆寫您想要自訂的特定方法,然後將您正在處理的視圖的無障礙委派設定為與新的委派相關聯。當開發人員設定 AccessibilityComponentType 時,原生程式碼會根據傳入的組件建立新的委派,並設定視圖以擁有該無障礙委派。

已做的變更

對於我們的新屬性,我們想要建立這兩個屬性的超集。我們決定讓新屬性主要仿照現有的屬性 accessibilityTraits 建模,因為 accessibilityTraits 具有顯著更多的值。這些特徵的 Android 功能將透過修改無障礙委派來進行 polyfill。

accessibilityTraits 在 iOS 上可以設定為 17 個 UIAccessibilityTraits 值。但是,我們沒有將所有這些值都包含在我們的新屬性的可能值中。這是因為設定其中一些特徵的效果實際上並不是很清楚,而且許多這些值實際上從未使用過。

UIAccessibilityTraits 值通常用於兩個目的之一。它們要么描述 UI 元素所具有的角色,要么描述 UI 元素所處的狀態。我們觀察到先前屬性的大多數用法通常使用一個代表角色的值,並將其與「state selected」、「state disabled」或兩者結合使用。因此,我們決定建立兩個新的無障礙屬性:accessibilityRoleaccessibilityState

accessibilityRole

新的屬性 accessibilityRole 用於告知 Talkback 或 Voiceover UI 元素的角色。這個新屬性可以採用以下其中一個值

  • 按鈕
  • 連結
  • 搜尋
  • 影像
  • 鍵盤按鍵
  • 文字
  • 可調整
  • 標頭
  • 摘要
  • 影像按鈕

此屬性僅允許傳入一個值,因為 UI 元素通常在邏輯上不會承擔多個角色。例外情況是影像和按鈕,因此我們新增了一個角色影像按鈕,它是兩者的組合。

accessibilityStates

新的屬性 accessibilityStates 用於告知 Talkback 或 Voiceover UI 元素所處的狀態。此屬性採用包含以下一個或兩個值的陣列

  • 已選取
  • 已停用

解決方案二:新增無障礙提示

為此,我們新增了一個新的屬性 accessibilityHint。設定此屬性將允許 Talkback 或 Voiceover 向使用者朗讀提示。

accessibilityHint

此屬性以字串形式接收要讀取的無障礙提示。

在 iOS 上,設定此屬性將在視圖上設定對應的原生屬性 AccessibilityHint。然後,如果 iPhone 中開啟了無障礙提示,Voiceover 將會朗讀提示。

在 Android 上,設定此屬性會將提示的值附加到無障礙標籤的末尾。此實作的優點是它模仿了 iOS 上提示的行為,但此實作的缺點是這些提示無法像在 iOS 上那樣在 Android 的設定中關閉。

我們在 Android 上做出此決定的原因是,通常無障礙提示與特定操作(例如點擊)相關聯,並且我們希望保持跨平台行為的一致性。

問題三的解決方案

accessibilityIgnoresInvertColors

我們將 Apple 的 api AccessibilityIgnoresInvertColors 公開給 JavaScript,因此現在當您有一個不想反轉顏色的視圖(例如影像)時,您可以將此屬性設定為 true,它就不會被反轉。

新用法

這些新屬性將在 React Native 0.57 版本中提供。

如何升級

如果您目前正在使用 accessibilityComponentTypeaccessibilityTraits,以下是您可以升級到新屬性的步驟。

1. 使用 jscodeshift

最簡單的用例可以使用執行 jscodeshift 腳本來取代。

腳本取代了以下實例

accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}

替換為

accessibilityRole= “trait”

此腳本也會移除 AccessibilityComponentType 的實例(假設您在任何設定 AccessibilityComponentType 的地方,也會設定 AccessibilityTraits)。

2. 使用手動程式碼修改 (codemod)

對於使用 AccessibilityTraits 但沒有對應的 AccessibilityRole 值的情況,以及將多個特徵傳遞到 AccessibilityTraits 的情況,則必須進行手動程式碼修改。

一般而言,

accessibilityTraits= {[“button”, “selected”]}

將手動替換為

accessibilityRole=“button”
accessibilityStates={[“selected”]}

這些屬性已在 Facebook 的程式碼庫中使用。Facebook 的程式碼修改非常簡單。jscodeshift 腳本修復了我們約一半的實例,而另一半則是手動修復的。總體而言,整個過程花費不到幾個小時。

希望您會覺得更新後的 API 很有用!並請繼續讓應用程式更易於存取!#包容性