[TOC=5]
* * * * *
>原文鏈接 :[Supporting Accessibility](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/SupportingAccessibility.html#//apple_ref/doc/uid/TP40007457-CH12-SW1)
一個好用的應用程序是每個人都可以使用的應用程序,包括那些有殘疾或身體障礙的應用程序,因為其功能和可用性作為有用的工具。 為了方便訪問,iOS 應用程序必須向 VoiceOver 提供有關其用戶界面元素的信息,以便視力受損的用戶可以與這些元素進行交互。 UIKit 對象默認是可訪問的,但仍然可以從視圖控制器的角度來解決可訪問性問題,其中包括:
* 確保界面中的每個用戶元素都是可訪問的,包括控件和靜態元素(如標簽)。
* 確保可訪問的元素提供準確和有用的信息。
通過以編程方式設置 VoiceOver 光標的位置,通過響應特定的 VoiceOver 手勢以及觀察輔助功能通知,您可以增強 VoiceOver 用戶在應用中的體驗。
### 將VoiceOver光標移至特定元素
當您的應用在屏幕上呈現新視圖時,請考慮設置 VoiceOver 光標的位置。當屏幕布局發生變化時,VoiceOver 對焦環(也稱為 VoiceOver 光標)會將其位置按從左到右,從上到下重新排列在屏幕上顯示的第一個元素上。將光標放在更合適的元素上可以加速用戶的界面導航。例如,將新的視圖控制器 push 到導航控制器的堆棧上時,VoiceOver 光標將落在導航欄的“后退”按鈕上。您可能需要將該光標移至導航欄的標題或新 push 的頁面上的元素。
要更改光標的位置,請使用 `UIAccessibilityPostNotification` 函數發布 `UIAccessibilityScreenChangedNotification` 通知。 通知會通知 VoiceOver 屏幕的內容已更改。 發布通知時,指定要分配焦點的元素,如清單6-1所示。
###### 清單 6-1 發送改變光標的輔助通知
~~~
@implementation MyViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// The second parameter is the new focus element.
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
self.myFirstElement);
}
@end
~~~
布局更改(包括由旋轉導致的布局更改)將重置VoiceOver光標的位置。 當您的視圖控制器的布局更改時,發布通知 `UIAccessibilityLayoutChangedNotification` 。 與 `UIAccessibilityScreenChangedNotification` 通知一樣,您可以指定要成為 VoiceOver 新的第一個元素的對象。
### 響應特殊的 VoiceOve r手勢
VoiceOver 定義了五種特殊手勢來觸發特定于應用程序的操作。
* **Escape**:雙指Z形手勢,用于解除模式對話框,或者返回導航層次結構中的一個級別。
* **Magic Tap**:雙指雙擊執行最有意的動作。
* **Three-Finger Scroll**:三指滑動,可以垂直或水平滾動內容。
* **Increment**:單指向上滑動即可增加元素中的值。
* **Decrement**:用一根手指向下滑動即可減少元素中的值。
使用這些手勢來執行視圖和視圖控制器的特定任務。 UIKit查找與手勢相對應的實現方法。 它使用響應者鏈搜索方法,從擁有 VoiceOver 焦點的元素開始。 如果沒有對象實現適當的方法,UIKit將為該手勢執行默認的系統操作。 例如,如果沒有從當前視圖到 app delegate 找到雙指雙擊手勢的實現,那么雙指雙擊手勢就會播放并暫停音樂應用的音樂播放。
盡管你可以在你的處理程序中采取任何你想要的動作,但語音用戶期望你的應用程序的行為遵循一定的指導方針。和任何手勢一樣,你的 VoiceOver 的實現應該遵循一種模式,以便與一個可訪問的應用程序的交互仍然是直觀的。
> 注意:
> 所有特殊的 VoiceOver 手勢方法都會返回一個布爾值,決定是否通過響應者鏈傳播。 要停止傳播,請返回 YES ; 否則,返回 NO 。
#### Escape
~~~
- (BOOL)accessibilityPerformEscape;
~~~
使用 `accessibilityPerformEscape` 方法來處理轉義手勢。 對于疊加內容(如彈出式對話框或警告框)的視圖,請使用該方法來消除疊加層。 Escape 手勢的功能就像電腦鍵盤上 Esc 鍵的功能一樣, 它會取消臨時對話框或表單以顯示主要內容。 您也可以使用 Escape 手勢實現在自定義導航層次結構中返回上一個界面。 如果您已經使用 UINavigationController 對象,則不需要實現此手勢,因為它已經處理此手勢。
#### Magic Tap
~~~
- (BOOL)accessibilityPerformMagicTap;
~~~
使用 `accessibilityPerformMagicTap` 方法來處理 Magic Tap 手勢。 Magic Tap 手勢快速執行常用或喜歡的操作。 例如,在“電話”應用程序中,“ Magic Tap”選取或掛斷電話,在“時鐘”應用程序中,“ Magic Tap”將啟動并停止秒表。 您可以使用此手勢來觸發與 VoiceOver 光標所在元素不相關的操作。 要在應用程序中的任何位置處理 Magic Tap 手勢,請在您的 app delegate 中實現 accessibilityPerformMagicTap 方法。
#### Three-Finger Scroll
~~~
- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction;
~~~
當 VoiceOver 用戶執行三指滾動手勢時,使用 `accessibilityScroll:`方法滾動自定義視圖的內容。 顯示書籍頁面的自定義視圖可以使用此手勢來翻頁。 傳遞給方法的參數指示了滾動的方向。
#### Increment and Decrement
~~~
- (void)accessibilityIncrement;
- (void)accessibilityDecrement;
~~~
使用 `accessibilityIncrement` 和 `accessibilityDecrement` 方法來增加或減少元素中的值。 具有 UIAccessibilityTraitAdjustable 特性的元素必須實現此方法。
### 觀察輔助功能通知
UIKit 發送輔助功能通知,通知您的應用程序相關的事件。 應用程序的對象可以觀察任何相關的通知,并使用它們執行相應的任務。 例如,iBooks 應用程序使用 `UIAccessibilityAnnouncementDidFinishNotification` 通知打開頁面,并在 VoiceOver 完成頁面最后一行的講話時進行翻頁繼續閱讀。 這種操作提供了一個無縫的,不間斷的閱讀體驗。
使用默認通知中心為輔助功能通知注冊觀察者。清單 6-2 顯示了一個視圖的例子,該視圖記錄一個公告的讀取是成功還是被用戶中斷。
###### 清單 6-2 注冊輔助功能通知觀察者
~~~
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(didFinishAnnouncement:)
name:UIAccessibilityAnnouncementDidFinishNotification
object:nil];
}
- (void)didFinishAnnouncement:(NSNotification *)dict
{
NSString *valueSpoken = [[dict userInfo] objectForKey:UIAccessibilityAnnouncementKeyStringValue];
NSString *wasSuccessful = [[dict userInfo] objectForKey:UIAccessibilityAnnouncementKeyWasSuccessful];
// ...
}
@end
~~~
另一個有用的通知是 `UIAccessibilityVoiceOverStatusChanged` 通知。 您可以使用該通知來檢測 VoiceOver 何時打開或關閉。 如果在您的應用程序被暫停時發生此通知,則當您的應用程序返回到前臺時,您會收到通知。
有關輔助功能通知的列表,請參閱 [ UIAccessibility Protocol Reference](https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility) 。