欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS無障礙適配西瓜視頻Voice?Over實(shí)踐示例

 更新時間:2022年05月18日 10:46:41   作者:字節(jié)跳動技術(shù)團(tuán)隊  
本文從研發(fā)的視角出發(fā),講述了如何使用?Voice?Over、如何適配?Voice?Over?以及適配過程中如果遇到問題應(yīng)該如何解決。希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

為了解決老年人、殘疾人等群體在使用互聯(lián)網(wǎng)等智能技術(shù)時遇到的困難,自 2021 年春季開始,西瓜視頻開展了無障礙與適老化改造專項行動。陸續(xù)完成了無障礙影院、色弱模式、護(hù)眼模式、大字號模式、外掛字幕等多個改造需求,充分滿足了視力障礙、聽力障礙以及老年人等特殊群體的需求。

一、Voice Over 簡介

Voice Over 旁白是蘋果手機(jī)自帶的工具。它能讓人們在不看屏幕的情況下了解頁面內(nèi)容和信息。盲人用戶在使用 iOS 設(shè)備時依賴 Voice Over 提供聽覺反饋。蘋果在自研的各類系統(tǒng)中均實(shí)現(xiàn)了 Voice Over 功能,如 OS X,iOS,watchOS 等等。透過 Voice Over 視障用戶可以在不同設(shè)備上獲得相同的體驗(yàn)。

使用旁白來訪問西瓜視頻的用戶有很多,“盲人小馬哥”就是其中的一位,感興趣的同學(xué)可以通過觀看他的視頻進(jìn)一步了解旁白。

二、Voice Over 使用指南

本節(jié)介紹了 Voice Over 開發(fā)者通常需要配置的開發(fā)環(huán)境。并以西瓜視頻為例,演示了 Voice Over 的基本操作。

Voice Over 開發(fā)環(huán)境配置

為了測試的方便,建議開發(fā)者可以將輔助功能快捷鍵設(shè)置成 VoiceOver 的切換,只需要連按三次右側(cè)開關(guān)鍵就能開啟/關(guān)閉 VoiceOver。

下方路徑中的 “通用” 適用于低版本系統(tǒng),高版本系統(tǒng)通過設(shè)置-> “輔助功能” 即可找到旁白

開啟/關(guān)閉 Voice Over(旁白)

設(shè)置 -> “通用” -> “輔助功能” -> “VoiceOver”(旁白)

設(shè)置連按三次右側(cè)開關(guān)鍵開啟/關(guān)閉 Voice Over(旁白) (開啟后可以便捷的打開/關(guān)閉旁白)

設(shè)置 -> “通用” -> “輔助功能” ->“輔助功能快捷鍵”,勾選 Voice Over 功能。

開啟 Voice Over+字幕面板 (開啟后可以便捷的查看旁白的全部朗讀文案)

設(shè)置 -> “通用” -> “輔助功能” ->“VoiceOver”->“字幕面板”

Voice Over 基本使用 —— 以西瓜為例

Voice Over 常用手勢詳解

這里主要例舉出 iOS 系統(tǒng)和西瓜視頻中最常用的手勢,完整操作可以參照蘋果官方文檔

https://support.apple.com/zh-cn/guide/iphone/iph3e2e3a6d/15.0/ios/15.0

入門手勢

  • 使用手勢進(jìn)行元素篩選

輕點(diǎn)或觸摸項目——選擇并朗讀項目

向右輕掃——選擇下一項

向左輕掃——選擇上一項

三指向某個方向滑動——翻頁操作,可以使 UIScrollView(包括 TableView、CollectionView)向某個方向翻動一頁

  • 使用手勢響應(yīng)元素事件

輕點(diǎn)兩下——響應(yīng)當(dāng)前元素的事件

輕點(diǎn)三下——雙擊當(dāng)前所選元素

雙指輕點(diǎn)兩下——響應(yīng)開發(fā)者定義的快捷事件 (如播放視頻、暫停視頻等)

雙指左右滑動(快速來回移動雙指三次,形成“Z”字形)——關(guān)閉彈窗或返回到上一級頁面

雙指輕點(diǎn)兩下并按住——用戶自定義元素名稱

進(jìn)階手勢

  • 使用手勢快速篩選元素

四指輕點(diǎn)屏幕頂部附近——選擇屏幕上的第一項

四指輕點(diǎn)屏幕底部附近——選擇屏幕上的最后一項

  • 使用“旁白”轉(zhuǎn)子

您可以使用轉(zhuǎn)子來更改“旁白”設(shè)置(如語速、遍歷方法等),在屏幕上從一個項目跳到下一個項目,以及選擇特殊輸入方法(如“盲文屏幕輸入”或“手寫”)等。有關(guān)詳細(xì)信息,請參閱在 iPhone 上使用轉(zhuǎn)子控制“旁白”

https://support.apple.com/zh-cn/guide/iphone/iph3e2e3a6d/15.0/ios/15.0

通過以下手勢來使用轉(zhuǎn)子。

雙指轉(zhuǎn)動——選取轉(zhuǎn)子設(shè)置

向上輕掃——移到上一項或調(diào)高(取決于轉(zhuǎn)子設(shè)置)

向下輕掃——移到下一項或調(diào)低(取決于轉(zhuǎn)子設(shè)置)

三、快速適配 Voice Over / 無障礙

想讓 App 達(dá)到無障礙基本可用并非難事,通過設(shè)置無障礙焦點(diǎn)、設(shè)置無障礙文案、調(diào)整焦點(diǎn)順序三步可以完成絕大多數(shù)的無障礙適配工作。本節(jié)對以上三步適配進(jìn)行了快速入門的介紹,并將西瓜首頁作為實(shí)戰(zhàn)案例為大家講解。

設(shè)置無障礙焦點(diǎn)

焦點(diǎn)是視力障礙用戶訪問應(yīng)用的唯一途徑,Voice Over 開啟時,如果一個元素沒有被設(shè)置為焦點(diǎn),那么該元素在屏幕中將不可被訪問。用戶可以通過在屏幕上移動焦點(diǎn)來“瀏覽”內(nèi)容。正確的焦點(diǎn)標(biāo)注和焦點(diǎn)順序能夠讓讀屏軟件用戶獲得更好的體驗(yàn)。

打開旁白后,系統(tǒng)會使用黑色框體框選當(dāng)前的焦點(diǎn)。通過輕觸某個位置 或 單指左右輕掃即可切換焦點(diǎn)。

  • 哪些場景需要焦點(diǎn):

除裝飾性組件以外的功能性組件都需要焦點(diǎn),如標(biāo)題、作者頭像、點(diǎn)贊、收藏、評論、更多等。

  • 哪些場景需要合并焦點(diǎn):

功能相同且距離近的焦點(diǎn)需要合并。如作者名稱、作者頭像(功能都是跳轉(zhuǎn)個人主頁,且距離近)。

需要高效篩選信息的場景需要合并,保留合并焦點(diǎn)的主功能,其余功能添加到轉(zhuǎn)子中,如 Feed。具體參照各業(yè)務(wù)方設(shè)計。

  • 如何設(shè)置無障礙焦點(diǎn):

針對絕大多數(shù)情況,我們可以利用以下的幾個屬性來調(diào)整焦點(diǎn)。

isAccessibilityElement:使用該屬性可以調(diào)整單個元素的無障礙可見性。對于大多數(shù) UI 基本元素,當(dāng)父控件為無障礙元素時,子控件將無法獲焦。

accessibilityElementsHidden:使用該屬性可以調(diào)整單個元素及其 subviews的無障礙可見性,一般用于屏蔽整個組件。

accessibilityViewIsModal:使用該屬性可以使該元素在同級 view中保持唯一可見性。常見場景見焦點(diǎn)被覆蓋時仍然可以被訪問。

設(shè)置無障礙文案

好的無障礙文案可以讓用戶清晰的了解到當(dāng)前焦點(diǎn)的目的,一般來說我們可以將元素按照按鈕、輸入框、搜索框等來劃分,從而進(jìn)行標(biāo)注。

當(dāng)我們參照“開發(fā)環(huán)境配置”配置好字幕后,旁白朗讀的文案將顯示在屏幕的底部。

  • 無障礙文案應(yīng)該包含什么:

無障礙文案需要能準(zhǔn)確描述一個焦點(diǎn)的功能及當(dāng)前的狀態(tài) (如 已選定、點(diǎn)贊、標(biāo)簽欄)。如果一個焦點(diǎn)包含多個不同的內(nèi)容,應(yīng)當(dāng)按照信息優(yōu)先級,將該焦點(diǎn)內(nèi)全部肉眼可見信息全部朗讀。

  • 如何配置無障礙文案:

從代碼層面來看,我們可以通過以下的幾個屬性來設(shè)置無障礙文案。

accessibilityLabel:一般來說,任意元素都需要設(shè)置 Label,Label 應(yīng)當(dāng)為短語 如:點(diǎn)贊、收藏;

accessibilityValue:(可選)用于經(jīng)常變化的標(biāo)簽數(shù)據(jù)類文案,例如 視頻的點(diǎn)贊按鈕的具體數(shù)值 (共 xxx 人);

accessibilityTraits:當(dāng)元素作為一個無障礙焦點(diǎn)時,我們需要描述該焦點(diǎn)的類別,如按鈕、已選中等。此時需要使用 Traits 對元素進(jìn)行標(biāo)記;

accessibilityHint:(可選)當(dāng)元素標(biāo)簽無法明確指出動作結(jié)果的時候,應(yīng)該給出一個提示;

accessibilityFrame:當(dāng)元素的焦點(diǎn)過小,需要手動調(diào)整焦點(diǎn)到較大值的時候,可以使用 Frame

VoiceOver 會把這幾個屬性連接起來,一般情況朗讀順序?yàn)?code>accessibilityLabel→accessibilityValueaccessibilityTraitsaccessibilityHint。

特例:accessibilitytraits中包含UIAccessibilityTraitSelected則會在最前方朗讀“已選定”。

調(diào)整焦點(diǎn)順序

焦點(diǎn)順序應(yīng)該遵循 從左往右 & 從上到下。正常情況下,焦點(diǎn)的順序與 SubViews 的順序一致,我們無需手動置頂焦點(diǎn)順序。如果焦點(diǎn)順序出現(xiàn)問題,我們可以利用 UIAccessibilityContainer 來調(diào)整屏幕中焦點(diǎn)的順序。

accessibilityElements:通過該屬性,我們可以指定一個元素包含的所有無障礙子元素。

UITableViewCell 中重設(shè)需要格外謹(jǐn)慎,可能會出現(xiàn)焦點(diǎn)循環(huán)問題。

以下圖為例,如果 C、D、E 是無障礙可視元素,通過如下設(shè)置我們就能使無障礙元素按照 D、E、C 的順序來排列。

A.accessibilityElements = @[B, C]
B.accessibilityElements = @[D, E]

西瓜首頁適配實(shí)戰(zhàn)

下面以西瓜首頁為示例,為大家演示無障礙的基礎(chǔ)適配。

以西瓜首頁為例,自上而下我們主要有五個區(qū)域需要設(shè)置焦點(diǎn)。分別是 搜索欄、頻道欄 & 頻道編輯器、作者動態(tài)欄 (Story)、視頻卡片 (卡片為一個焦點(diǎn),用戶通過轉(zhuǎn)子進(jìn)行其他操作)、底部 Tab 選擇器。下面針對每個部分進(jìn)行無障礙適配的解釋。

搜索欄

searchBox.isAccessibilityElement = YES;
searchBox.accessibilityLabel = @"搜索框";
searchBox.accessibilityValue = @"熱搜詞1,第一座4萬億GDP的城市。熱搜詞2,南昌至臺灣專列開通";
searchBox.accessibilityTraits = UIAccessibilityTraitSearchField;

頻道欄 & 頻道編輯器

/// 頻道欄的無障礙適配
categoryCell.isAccessibilityElement = YES;
categoryCell.accessibilityLabel = @"推薦頻道";
categoryCell.accessibilityVaule = @"熱搜詞1,第一座4萬億GDP的城市。熱搜詞2,南昌至臺灣專列開通";
categoryCell.accessibilityHint = @"輕點(diǎn)兩下切換首頁頻道";
/// 未選中時
categoryCell.accessibilityTraits = UIAccessibilityTraitTabBar;
/// 已選中時
categoryCell.accessibilityTraits = UIAccessibilityTraitTabBar|UIAccessibilityTraitSelected;
/// 頻道編輯器的無障礙適配
// 如果面板是以addSubview的形式添加到界面上時,需要屏蔽底層元素的訪問
@implementation categoryEditViewController
- (void)viewDidAppear {
    categoryEditView.accessibilityViewIsModal = YES;
    /// 使用戶焦點(diǎn)移動到頻道編輯面板上。
    UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, categoryEditView);
}
- (void)viewDidDisAppear {
    categoryEditView.accessibilityViewIsModal = NO;
}
@end

作者動態(tài)欄

storyCell.isAccessibilityElement = YES;
storyCell.accessibilityLabel = isLive ?  @"入江閃閃,正在直播" : @"入江閃閃";
storyCell.accessibilityHint = isLive ? @"輕點(diǎn)兩下進(jìn)入作者直播觀看視頻" : @"輕點(diǎn)兩下進(jìn)入作者視頻列表播放視頻";
@implementation storyCell
// TableView與CollectionView嵌套時,cell可能會出現(xiàn)無法自然滾動的問題。
- (void)accessibilityElementDidBecomeFocused {
    [self.collectionView scrollToIndexPath:self.indexPath];
}
@end

視頻列表

videoCell.isAccessibilityElement = YES
videoCell.accessibilityLabel = [視頻標(biāo)題、作者名稱、點(diǎn)贊數(shù)、收藏數(shù)、評論數(shù)等]
videoCell.accessibilityHint = @"輕點(diǎn)兩下進(jìn)入詳情頁播放視頻,上下輕掃使用轉(zhuǎn)子訪問更多功能"
UIAccessibilityCustomAction * action1 = [[UIAccessibilityCustomAction alloc] initWithName:@"點(diǎn)贊" target:self selector:@selector(action1)];
UIAccessibilityCustomAction * action2 = [[UIAccessibilityCustomAction alloc] initWithName:@"收藏" target:self selector:@selector(action2)];
UIAccessibilityCustomAction * action3 = [[UIAccessibilityCustomAction alloc] initWithName:@"更多" target:self selector:@selector(action3)];
videoCell.accessibilityCustomActions = @[action1,action2,action3];

四、Voice Over 相關(guān)協(xié)議介紹

UIAccessibility 無障礙標(biāo)簽標(biāo)注

@interface NSObject (UIAccessibility)
/// 標(biāo)記一個元素是否是無障礙元素
@property (nonatomic) BOOL isAccessibilityElement;
/// 標(biāo)記一個元素的無障礙元素的簡短描述 如 (點(diǎn)贊、收藏)
@property (nullable, nonatomic, copy) NSString *accessibilityLabel;
/// (可選)標(biāo)記一個元素的無障礙元素的詳細(xì)描述 如 (輕點(diǎn)兩下與xxx人一起點(diǎn)贊,輕點(diǎn)兩下將視頻添加到收藏列表)
@property (nullable, nonatomic, copy) NSString *accessibilityHint;
/// (可選)標(biāo)記一個元素的無障礙元素的具體值,如50%等
@property (nullable, nonatomic, copy) NSString *accessibilityValue;
/// (可選)標(biāo)記一個元素的無障礙特征 如(按鈕、標(biāo)簽夾等)
@property (nonatomic) UIAccessibilityTraits accessibilityTraits;
/// (可選)自定義一個元素的無障礙模式下的焦點(diǎn)大小
@property (nonatomic) CGRect accessibilityFrame;
@end

UIAccessibilityAction 無障礙手勢響應(yīng)

@interface NSObject (UIAccessibilityAction)
/// 自定義無障礙事件,可以使點(diǎn)擊事件與普通用戶隔離。
- (BOOL)accessibilityActivate API_AVAILABLE(ios(7.0));
/// 當(dāng)元素被定義為可變元素時,可以實(shí)現(xiàn)下面的方法。如音量、亮度調(diào)節(jié)器。
- (void)accessibilityIncrement API_AVAILABLE(ios(4.0));
- (void)accessibilityDecrement API_AVAILABLE(ios(4.0));
- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction API_AVAILABLE(ios(4.2));
/// 通常浮窗或頁面需要實(shí)現(xiàn)該方法,實(shí)現(xiàn)該方法后用戶可以使用“Z”字形手勢退出頁面
- (BOOL)accessibilityPerformEscape API_AVAILABLE(ios(5.0));
/// 該方法可以接收到用戶的雙指雙擊事件??梢杂糜趶棾龈嗝姘?or 定義一些重要操作如 暫停。
- (BOOL)accessibilityPerformMagicTap API_AVAILABLE(ios(6.0));
/// 轉(zhuǎn)子的核心方法,給accessibilityCustomActions賦值后可以上下輕掃訪問轉(zhuǎn)子
@property (nullable, nonatomic, strong) NSArray <UIAccessibilityCustomAction *> *accessibilityCustomActions API_AVAILABLE(ios(8.0));
@end

UIAccessibilityFocus 無障礙焦點(diǎn)響應(yīng)

@interface NSObject (UIAccessibilityFocus)
/// 焦點(diǎn)響應(yīng)事件,可以捕獲元素是否成為了焦點(diǎn)。通常重寫這兩個方法。
- (void)accessibilityElementDidBecomeFocused API_AVAILABLE(ios(4.0));
- (void)accessibilityElementDidLoseFocus API_AVAILABLE(ios(4.0));
/// 可以判斷該元素是否被聚焦,通常不要處理該方法。
- (BOOL)accessibilityElementIsFocused API_AVAILABLE(ios(4.0));
@end

UIAccessibilityContainer 無障礙自定義焦點(diǎn)

@interface NSObject (UIAccessibilityContainer)
/// 返回當(dāng)前容器無障礙元素的總數(shù)
- (NSInteger)accessibilityElementCount NS_SWIFT_UI_ACTOR;
/// 返回對應(yīng)index的元素
/// 需要保證返回的是真實(shí)存在的實(shí)例(不能為alloc出來的)
- (nullable id)accessibilityElementAtIndex:(NSInteger)index NS_SWIFT_UI_ACTOR;
/// 返回對應(yīng)元素的index
- (NSInteger)indexOfAccessibilityElement:(id)element NS_SWIFT_UI_ACTOR;
??如果使用上面的三個方法,一般需要同時全部實(shí)現(xiàn)。
??如果實(shí)現(xiàn)了上面的三個方法,那么就不要再手動設(shè)置accessibilityElements
/// 容器的無障礙元素List,設(shè)置后頁面無障礙元素范圍將會被限制在List內(nèi),順序與List內(nèi)元素順序相同。
@property (nullable, nonatomic, strong) NSArray *accessibilityElements API_AVAILABLE(ios(8.0)) NS_SWIFT_UI_ACTOR;
/// default == UIAccessibilityContainerTypeNone,絕大多數(shù)情況保持None即可。如果手動設(shè)置Type則需要實(shí)現(xiàn)對于Type的指定協(xié)議。
@property (nonatomic) UIAccessibilityContainerType accessibilityContainerType API_AVAILABLE(ios(11.0)) NS_SWIFT_UI_ACTOR;
@end

五、常見問題與解決方案

該部分根據(jù)西瓜真實(shí)的業(yè)務(wù)實(shí)踐,列舉了數(shù)個常見無障礙問題的修復(fù)方案。例如:焦點(diǎn)目的不明確、焦點(diǎn)亂跳問題、嵌套容器 ScrollView 無法跟隨滾動等。

焦點(diǎn)缺失/焦點(diǎn)冗余

焦點(diǎn)缺失是無障礙 Bug 中最基礎(chǔ)但最嚴(yán)重的問題。極端情況情況下會產(chǎn)生致命的阻塞性的 Bug(如返回按鈕缺失焦點(diǎn))。通常而言產(chǎn)品上一些按鈕、鏈接、勾選框、圖片、編輯框等需要焦點(diǎn)方便用戶交互。

此外焦點(diǎn)冗余也會嚴(yán)重影響用戶的使用體驗(yàn),一些裝飾性元素焦點(diǎn)冗余后,用戶的信息篩選效率會嚴(yán)重降低。通常而言,用戶點(diǎn)擊后無明確響應(yīng)事件的組件不應(yīng)該成為焦點(diǎn)。

「解決方法」:一般情況下,系統(tǒng)會自動給標(biāo)準(zhǔn)控件 UIButton 等交互控件添加焦點(diǎn),其他自定義控件需要手動添加/更改。一般情況下手動指定屬性isAccessibilityElement為 YES 或者 NO 可解決該問題。

self.isAccessibilityElement = YES;
self.accessibilityLabel = @"點(diǎn)贊";  // 通常焦點(diǎn)描述也會缺失,需要一并補(bǔ)充。
/// 對于一些自定義的UI控件,也可以重寫上述兩個對象的Get方法。
- (NSString *)accessibilityLabel {
    return @"點(diǎn)贊";
}
- (BOOL) isAccessibilityElement {
    return YES;
}

焦點(diǎn)過細(xì)/焦點(diǎn)合并

焦點(diǎn)合并指的是有相同目的、相同操作的,或具有組合意義的組合視圖,焦點(diǎn)沒有合并的情況,問題描述為“合并焦點(diǎn)”。例如,好友列表中的好友頭像和昵稱應(yīng)合并為一個焦點(diǎn),二者功能都一樣,都是跳轉(zhuǎn)到個人資料界面。

「解決方法」:在需要合并焦點(diǎn)的 superView 處將 isAccessibilityElement 設(shè)置為 YES。

self.isAccessibilityElement = YES;

焦點(diǎn)信息錯誤 (目的不明確,信息冗余等)

焦點(diǎn)目的不明確是指頁面中的焦點(diǎn)僅朗讀出基本文案,但是未朗讀該控件的類型(按鈕、標(biāo)簽欄、鏈接等),或者未朗讀該焦點(diǎn)響應(yīng)后會發(fā)生的事件(輕點(diǎn)兩下進(jìn)入詳情頁播放視頻等)。

「解決方法」:參照產(chǎn)品的無障礙標(biāo)注規(guī)范。調(diào)整問題焦點(diǎn)的 accessibilityLabel、accessibilityTraits、accessibilityHint 等字段,從而使焦點(diǎn)信息朗讀準(zhǔn)確。

/// Button
// 點(diǎn)贊按鈕未被選中時
self.accessibilityTraits = UIAccessibilityTraitButton;
self.accessibilityHint = @"輕點(diǎn)兩下與xxx人一同點(diǎn)贊";
// 點(diǎn)贊按鈕被選中時
self.accessibilityTraits = UIAccessibilityTraitButton|UIAccessibilityTraitSelected;
self.accessibilityHint = @"輕點(diǎn)兩下取消點(diǎn)贊";
///TabBar(包括頂Tab和底Tab)
// 當(dāng)對象為TabBar
self.accessibilityTraits = UIAccessibilityTraitTabBar
// 被選中的TabBar
self.accessibilityTraits = UIAccessibilityTraitTabBar|UIAccessibilityTraitSelected;

焦點(diǎn)停留不當(dāng)

頁面刷新后跑焦點(diǎn)、對視圖或控件進(jìn)行操作后跑焦點(diǎn),打開新界面焦點(diǎn)停留的位置不適當(dāng),問題描述為“焦點(diǎn)停留不當(dāng)”。例如進(jìn)入一些頁面后,焦點(diǎn)默認(rèn)停留在原位置,或者停留在新頁面的返回按鈕。

「解決方法」:在進(jìn)入界面時將 VoiceOver 焦點(diǎn)定位到特定控件??梢允褂?code>UIAccessibilityPostNotification發(fā)送通知給特定控件,改變 voiceOver 焦點(diǎn)。

@implementation MyViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
self.myFirstElement);
}
@end

焦點(diǎn)順序錯誤問題

焦點(diǎn)順序不符合邏輯順序時,通常描述為:“焦點(diǎn)順序不符合邏輯順序”;焦點(diǎn)順序不符合視覺順序時,描述為“焦點(diǎn)順序不符合視覺順序”。

「解決方法」:手動設(shè)置 accessibilityElements。極端場景下可以主動實(shí)現(xiàn) UIAccessibilityContainer 協(xié)議。

/// 普通場景. 切勿在TableView的Cell中使用
self.accessibilityElements = @[View1,View2,View3];
/// 復(fù)雜場景,務(wù)必將三個方法都實(shí)現(xiàn),否則容易出現(xiàn)意料之外的問題
- (NSInteger)accessibilityElementCount {
    return 3;
}
- (nullable id)accessibilityElementAtIndex:(NSInteger)index {
    return Views[index];
}
- (NSInteger)indexOfAccessibilityElement:(id)element {
    return [Views indexOfObject:element];
}

焦點(diǎn)選中時亂跳問題

該問題主要發(fā)生在 CollectionView 上,一般現(xiàn)象為調(diào)整一個 Cell 的選中態(tài)并 reloadData,焦點(diǎn)會先轉(zhuǎn)移到一個隨機(jī)的位置(一般是選中 Cell 的后一個),而后再跳回正確的位置。

「解決方法」:慎用 UICollectionView、UITableView 的 reloadData。當(dāng)需要刷新 Cell 的選中狀態(tài)時,盡量自己實(shí)現(xiàn)一個 updateVisibleCell。reloadData 時會導(dǎo)致 Cell 隨機(jī)復(fù)用,最終產(chǎn)生焦點(diǎn)亂跳的異常。

?
[self reloadData];
?
[self updateVisibleCells];
- (void)updateVisibleCells {
  NSArray<UICollectionViewCell *> *visibleCells = self.collectionView.visibleCells;
  [visibleCells enumerateObjectsUsingBlock:^(UICollectionViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    // Todo something
  }];
}

浮窗問題 / 焦點(diǎn)被覆蓋時仍可訪問

在西瓜視頻中,浮窗有多種不同的存在形式,如 XIGAlert(隱私彈窗等)、XIGToast(網(wǎng)絡(luò)異常等)、半屏浮窗(鍵盤、清晰度面板、倍速面板等)。在彈窗出現(xiàn)時,用戶可以通過左右滑動切換焦點(diǎn)至不可視的視圖。這些視圖產(chǎn)生的相關(guān)事件可能會使程序崩潰,發(fā)生一些意料之外的事情。

「解決方法」:一般做法為讓底層控件元素失去焦點(diǎn)來達(dá)到屏蔽底層元素的效果,將灰色變暗區(qū)域設(shè)為單個大焦點(diǎn),標(biāo)簽設(shè)為 “關(guān)閉” 或 “收起” 等提示,雙擊可關(guān)閉浮層。彈窗或彈層時,自動使上層容器的第一控件(如標(biāo)題或通知內(nèi)容)獲取焦點(diǎn),視障用戶無須二次切換焦點(diǎn),更符合視障用戶使用體驗(yàn),更加體現(xiàn)人性化。

self.accessibilityViewIsModal = YES

對蒙層設(shè)置屬性,會使蒙層的同級 view不響應(yīng) VoiceOver,而蒙層的子 view 可響應(yīng)。如下圖所示,如果希望 E 可以被訪問,CD 不可被訪問,此時需要設(shè)置 B 的accessibilityViewIsModal為 YES。

嵌套容器 ScrollView 無法跟隨滾動問題

在 UICollectionView 中,嵌套一個 UIScrollView 或者 UITableView,焦點(diǎn)在 TableView、ScrollView 中滑動時,不會發(fā)生自動滾動,從而導(dǎo)致頁面發(fā)生白屏等現(xiàn)象。

「解決方法」:使用 accessibilityActivate,在焦點(diǎn)聚焦到一個 Cell 上的時候,手動調(diào)用

scrollToRowAtIndexPath: atScrollPosition: animated:

如果一個 Cell 中包含多個功能,Cell 還需要進(jìn)行轉(zhuǎn)子適配。

- (BOOL)accessibilityElementDidBecomeFocused {
   [self.tableview scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
   return YES;
}

橫滑拖拽問題(手勢替代問題)

在應(yīng)用中有許多場景有橫滑手勢,如橫滑刪除,橫滑編輯等。此類事件在 Voice Over 開啟時無法被響應(yīng)。故需要通過一些其他手段使用戶能夠訪問到橫滑的功能。

「解決方法」:使用轉(zhuǎn)子對功能進(jìn)行改造。

UIAccessibilityCustomAction * action1 = [[UIAccessibilityCustomAction alloc] initWithName:@"進(jìn)入詳情頁" target:self selector:@selector(action1)];
UIAccessibilityCustomAction * action2 = [[UIAccessibilityCustomAction alloc] initWithName:@"刪除該視頻" target:self selector:@selector(action2)];
UIAccessibilityCustomAction * action3 = [[UIAccessibilityCustomAction alloc] initWithName:@"隱藏該視頻" target:self selector:@selector(action3)];
self.accessibilityCustomActions = @[action1,action2,action3];

以上就是iOS無障礙適配西瓜視頻Voice Over實(shí)踐示例的詳細(xì)內(nèi)容,更多關(guān)于iOS適配Voice Over的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論