介紹
1.開啟voiceOver
設置->通用->輔助功能->VoiceOver
在voiceOver模式中
a.輕觸一次是選中控件
b.雙擊激活
c.三只手指滾動視圖
2.效果
當用戶在選擇了指定交互元素的時候,VoiceOver “說”給用戶聽這個元素 的信息和使用提示,而這個元素的輔助功能標簽和提示告訴 VoiceOver 應該如何“說”給用戶聽。
比如 當你 輕觸導航欄中的“返回”按鈕,voiceOver會告訴你 ?"返回 按鈕";在官網提供的VoiceOver介紹中有張圖進行了介紹
3.UIAccessibility屬性說明
label(標簽)一個簡短的本地化詞或短語,此短語簡潔地描述控件或者視圖,但是不能識別元素類型。例如“添加”、“播放”。
traits(特性)一個或多個獨立特征的組合。每個特征描述一個元素狀態、行為、使用中的某一方面。例如當元素的行為如同被選中鍵盤上的按鍵,這個元素就有了Keyboard Key和Selected的組合特征。
hint(提示)一個簡短的本地化短語,描述發生在元素上動作的結果。例如“添加標題”或者“打開購物列表”。
frame(框架)元素在屏幕上坐標的框架。由CGRect結構體提供,詳細說明了元素的屏幕位置和大小。
value(值)不是由標簽定義的元素時的當前值。例如,一個幻燈片的標簽可以是”速度”,但是它當前的值是“50%”
tips:
1) UIAccessibilityElement都必須有frame和label屬性
2)?僅當元素的內容是可改變并且永不被label描述時,一個無障礙元素才需要提供給值屬性提供內容。例如,一個文本域包含了一個可能有Email標簽的Email地址,但是它的內容取決于用戶的輸入,通常格式為”username@address。“value提供了一個動態更新的方式
3)voiceOver朗讀的順序 ?label->traits->hint
實現細節
4.UI Accessibility編程接口
UIAccessibility (informal protocol)實現UIAccessibility協議的對象可以報告無障礙狀態(即他們是否是無障礙的)并且提供關于自身的描述信息。UIAccessibility協議默認由標準UIKit控件和視圖都有實現,比如說某些UIView子類、UIButton,UILabel都默認實現了,voiceOver可以朗讀其信息,可以自定義其屬性VoiceOver朗讀的信息
UIAccessibilityContainer(informal protocol)
當非UIView子類的對象被UIView視圖包含時,這些元素不會自動變成無障礙元素,此時UIAccessibilityContainer協議就非常有用。
UIAccessibilityElement(class)
定義了一個對象是否能通過UIAccessibilityContainer協議返回。你可以創建UIAccessibilityElement實例來代表無法自動變為無障礙的元素,例如一個沒有繼承自UIView的對象,或者一個不存在的對象。
UIAccessibilityConstants.h (header file)
此頭文件定義了用來描述某些特征的常量。這些常量即 可展示的無障礙元素,還有可被應用發布的通知。
5.模擬器中使用VoiceOver
在xcode編程,模擬器打開VoiceOver后,可以看到
其中Accessibility Inspector是展示元素的可用性,
Label 對應 accessibilityLabel屬性,控件信息,觸摸時首先被朗讀的
Traits 對應 accessibilityTraits屬性,控件類型和特征,比如說 按鈕、變灰
Frame 對應 accessibilityFrame屬性 ,朗讀時在屏幕上顯示的聚焦框位置和大小,一般不需改動。
可以通過編寫代碼
button.accessibilityLabel = @"請點擊一下";
button.accessibilityHint = @"可以進入到新頁面";
可以得到結果,voiceOver信息就會變成請點擊一下 ?按鈕 ? ?可以進入到新頁面
6.針對幾種元素進行VoiceOver開發
(1)標準控件
標準控件默認支持VoiceOver,只需要通過UIAccessibility接口設置對應的屬性就可以達到大部分的無障礙支持需求,用的比較多的屬性有:
accessibilityLabel:此屬性用于描述控件的功能或內容,當用戶觸摸到控件區域,就會播放相應的描述內容;accessibilityTraits:UIAccessibilityTraits,用于描述控件的特性,是一個組合屬性,即可以通過多個UIAccessibilityTraits或操作組合屬性。對于標準控件,都有其默認值描述對應控件的特征,而自定義控件的默認值為UIAccessibilityTraitNone,舉個例子,UIButton該屬性默認值為UIAccessibilityTraitButton,當用戶觸摸時將會播放accessibilityLabel的描述內容+“按鈕”,如果按鈕被disable,則應該像如下設置此屬性,表示該元素 是 按鈕且變灰(點擊無效)
stopElement.accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled;
accessibilityHint:用于描述控件激活后的動作,一般是一個動詞開頭的短語;
accessibilityElementsHidden:是一個BOOL屬性,用于隱藏控件,使控件不響應VoiceOver觸摸,設置控件的hidden屬性只能隱藏控件的可視區域,但是對VoiceOver是無效的,如果要使控件不響應VoiceOver,將此屬性設置為YES.
(2)自定義控件(UIView的某些子類)
默認情況下自定義控件是不支持VoiceOver的。可以通過兩種方式使其支持VoiceOver:
1)實現isAccessibilityElement協議,在UIView子類中實現此協議返回YES;
2)直接設置isAccessibilityElement屬性,將其設置為YES; 自定義其他屬性和標準控件一樣
tips:
a.父View如果設置isAccessibilityElement為YES,則其子View將都不能相應VoiceOver,如果如果需要兩個View都支持VoiceOver,只能改變他們的層次結構,并都設置為isAccessibilityElement.
b.在某些情況下,希望控件在VoiceOver模式下直接處理touch事件,比如,畫圖功能,畫布需要處理觸摸事件,而在voiceOver開啟的情況下,touch事件會被block,這時就需要設置畫布的accessibilityTraits: paintCanvas.accessibilityTraits |= UIAccessibilityTraitAllowsDirectInteraction;
(3)其他情況
在自定義view中有時包含了一些非標準控件也非UIView子類的可觸摸UI原素,比如通過draw方法畫出來的區域,則以上的兩種情況都不能實現無障礙體驗,這種情況下,則需要實現UIAccessibilityContainer Protocol來實現.UIAccessibilityContainer Protocol是非正式協議,只需要實現以下接口:
1)定義一個NSMutableArray屬性 用于保存所有的accessible Elements. @property(nonatomic, strong) NSMutableArray *accessibleElements;
2)– (NSInteger)accessibilityElementCount方法,返回Element個數;
3)– (id)accessibilityElementAtIndex:(NSInteger)index;返回對應index下的UIAccessibilityElement;
4)實現- (bool)isAccessibilityElement;返回NO,正如之前提到,父View如果為AccessibilityElement,子element將不響應voiceover,所以這里要返回NO; 在生成每個區域的UIAccessibleElement需要定義element關聯的frame,,其它的和標準控件一致,舉例子(在官網中也有例子說明),比如如下這段:
UIAccessibilityElement *element = [[UIAccessibilityElement alloc]initWithAccessibilityContainer:self];
element.accessibilityFrame = [self convertRect:_nameLabel.frame toView:nil];
element.accessibilityLabel = NSLocalizedString( _nameLabel.text, nil);
element.accessibilityTraits = UIAccessibilityTraitStaticText;
[_accessibilityElements addObject:element];
(4)通知
1)在進入界面是將VoiceOver焦點定位到特定控件。可以使用UIAccessibilityPostNotification發送通知給特定控件,改變voiceOver焦點:
@implementation MyViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
self.myFirstElement);
}
@end
2)直接播一段語音
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @"something to read aloud");
(5)其他
長按在voiceOver下的操作:選中,輕點兩下,再按住;解釋見
http://www.applevis.com/forum/ios-ios-app-discussion/how-do-you-perform-long-press-action-using-voice-over
參考資料
http://nshipster.cn/uiaccessibility/
http://useyourloaf.com/blog/voiceover-accessibility.html
http://bupojung.github.io/blog/2014/06/24/wei-mang-ren-dao-hang-voiceoverzong-jie/