原創(chuàng)文章迎捺,如需轉(zhuǎn)載請(qǐng)?jiān)谙旅媪粞宰屛抑??营搅。不留言不在開頭標(biāo)明出處鏈接的壞同學(xué)筷转,1字1元索賠??
一直想談?wù)?iOS 中的 Accessibility蔚万,很多做了多年 iOS 開發(fā)的同學(xué)竟然不知道這是什么。仔細(xì)想想??徽曲,我自己也不是特別清楚??零截,只知道這個(gè)東西對(duì)殘疾人和應(yīng)用的自動(dòng)化測(cè)試都很重要,今天恰好看到了一篇非常不錯(cuò)的英文博客疟位,那就順便翻譯一下吧??
文章閱讀時(shí)間大約30分鐘
為什么要用 Accessibility瞻润?
在我們開始編碼之前,一定要理解 Accessibility 帶來的好處甜刻。
- 使用 Accessibility 設(shè)計(jì)我們的應(yīng)用绍撞,不論是使用 KIF 框架還是 Xcode 中的 UI Testing 進(jìn)行測(cè)試,都會(huì)更加容易得院。
- 你還可以通過讓更多群體的人使用你的 App傻铣,從而拓寬你的市場(chǎng)和用戶基礎(chǔ)。
- 如果你在政府機(jī)構(gòu)工作祥绞,必須遵守508 條例非洲,該條例規(guī)定所有用戶都必須可以使用任何軟件或技術(shù)。(譯者注:條例508是1973年頒布的美國(guó)勞工康復(fù)法案(Rehabilitation Act)的修正條例蜕径,這條聯(lián)邦法例規(guī)定殘疾人有權(quán)使用所有聯(lián)邦政府發(fā)展两踏、促成、維持或使用的電子和信息技術(shù)兜喻。)
- 在你的應(yīng)用中實(shí)現(xiàn) Accessibility梦染,表示你愿意為每個(gè)用戶做更多的努力,這是件好事。
- 很高興了解到你正在做一件讓某個(gè)人的生活發(fā)生微小而又顯著的改變的事??
說服你了嗎帕识?
各界人士泛粹,各個(gè)年齡段和來自不同背景的人都在使用智能手機(jī)上的 App,其中包括殘疾人肮疗。在設(shè)計(jì) App 的時(shí)候要考慮到可用性晶姊,以幫助那些視覺、行動(dòng)伪货、學(xué)習(xí)或聽力有障礙的人使用你的 App们衙。
在這篇 iOS accessibility 教程中,我們會(huì)把一個(gè)已有的 App 變得讓視力障礙的人更容易使用超歌。在這過程中砍艾,你會(huì)學(xué)到:
- 如何使用 VoiceOver(旁白)(譯者注:旁白是一款可與 app 中的對(duì)象進(jìn)行交互的屏幕閱讀器,使用該功能的用戶即使看不到界面巍举,也可以操控界面。)
- 如何使用 Accessibility Inspector 檢查你的 App
- 如何使用 UIKit 實(shí)現(xiàn) accessibility 元素
- 如何為殘疾人構(gòu)建一個(gè)更好的用戶體驗(yàn)
這個(gè)教程需要用到 Xcode 11.3 和 Swift 5.1凝垛。本教程假定你已經(jīng)了解了基礎(chǔ)的 Swift 開發(fā)懊悯。如果你還沒接觸過Swift,可以先學(xué)習(xí)一下這本書 Swift Apprentice梦皮。
注意:你得有一個(gè)真機(jī)才能使用 VoiceOver炭分。輔助功能現(xiàn)在還不支持模擬器。
開始
在這個(gè)教程里面剑肯,我們會(huì)用到一個(gè)已經(jīng)做好的捧毛,叫食譜(Recipe)的應(yīng)用。這個(gè)應(yīng)用包括一個(gè)食譜列表让网,每種食譜都一個(gè)制作難度等級(jí)呀忧。你還可以給自己做的菜進(jìn)行評(píng)價(jià)。
點(diǎn)擊原文下載鏈接(或使用:https://pan.baidu.com/s/1XcYX2fp2YwNJUDs5zy6wQg 密碼:33gp)溃睹,這里面包括我們要用到的所有東西而账。打開 begin 文件夾中的 Recipe.xcodeproj。
在你的設(shè)備上運(yùn)行這個(gè)應(yīng)用之前因篇,需要修改一下工程的簽名配置泞辐。
在 Xcode 左側(cè)導(dǎo)航欄點(diǎn)擊 Recipe 工程,之后選擇同名的 target竞滓。選擇 Signing & Capabilities 頁面咐吼,之后在頂部點(diǎn)擊 Debug。最后從下拉菜單選擇你的 Team商佑。
了解一個(gè)這個(gè) Recipe 應(yīng)用
現(xiàn)在锯茄,構(gòu)建運(yùn)行這個(gè) App,熟悉一下它的功能
根視圖控制器是一個(gè)包含圖片的食譜列表莉御,還有食物描述和制作難度等級(jí)撇吞。點(diǎn)擊一個(gè)食譜俗冻,可以看到一個(gè)大圖和食物的原料、制作方法牍颈。
還有更好玩的迄薄,你可以劃掉原料列表中的條目,以確保你已經(jīng)加入了必要的食材煮岁。還可以點(diǎn)擊右上角的喜歡??/不喜歡??的emoji表情讥蔽,表示你喜不喜歡自己做的食物。
食譜 App 的幕后
花幾分鐘自己熟悉一下 begin 文件夾中的工程源碼画机。以下是一些要點(diǎn):
- Main.Storyboard 包含 App 的所有視圖場(chǎng)景冶伞。你應(yīng)該已經(jīng)注意到了,所有的 UI 元素都是標(biāo)準(zhǔn)的 UIKit 控件和視圖步氏∠烨荩控件已經(jīng)開啟了輔助功能。
-
RecipeListViewController.swift 管理根列表(table)視圖荚醒,顯示所有的食譜芋类。使用一個(gè)
Recipe
對(duì)象做數(shù)據(jù)源(data source)。 - Recipe.swift 是數(shù)據(jù)模型對(duì)象界阁,表示一個(gè)食譜侯繁。它包括加載所有食譜數(shù)組的工具方法,這些食譜將貫穿我們使用整個(gè)應(yīng)用泡躯。
-
RecipeCell.swift 是食譜列表根視圖控制器的單元格(cell)贮竟。它會(huì)基于
Recipe
模型對(duì)象的數(shù)據(jù),顯示食譜的難度級(jí)別较剃、名稱和照片咕别。 -
RecipeInstructionViewController.swift 包括詳情視圖的控制器代碼,用于展示食物的大圖重付、原材料和烹飪方法顷级。它有一個(gè)
UISegmentedControl
,用于切換原料和烹飪方法确垫,其中烹飪方法是一個(gè)列表視圖并用到了InstructionViewModel
弓颈。 -
InstructionViewModel.swift 扮演著
RecipeInstructionsViewController
的數(shù)據(jù)源的角色。包括原材料和烹飪方法的描述删掀、復(fù)選框(check box)的狀態(tài)信息翔冀。 - InstructionCell.swift 定義了一個(gè)單元格,包含一個(gè)標(biāo)簽 (label) 和一個(gè)復(fù)選框披泪,用于烹飪方法和原材料的列表纤子。當(dāng)我們勾選了復(fù)選框,這個(gè)單元格會(huì)把自己的文字畫上中劃線。
至此控硼,你已經(jīng)理解了這個(gè)應(yīng)用的運(yùn)行原理泽论,是時(shí)候考慮怎么讓它更加易用了。
開啟 VoiceOver
iOS 自帶 VoiceOver 這個(gè)屏幕閱讀工具卡乾,它讓用戶無需觀看屏幕就可以和軟件進(jìn)行交互翼悴。是專門為視力有問題的人士設(shè)計(jì)的。
VoiceOver 讓視力受損的用戶可以聽到屏幕上的可視內(nèi)容幔妨,并和它們進(jìn)行交互鹦赎。VoiceOver 會(huì)響應(yīng)手勢(shì),并以聲音的方式向用戶傳達(dá)屏幕上的內(nèi)容或用戶選擇的內(nèi)容误堡。本質(zhì)上古话,VoiceOver 是 UI 和用戶觸控輸入之間的鏈接。
使用 VoiceOver 最便捷的方法是打開你設(shè)備上的設(shè)置锁施,點(diǎn)擊輔助功能 ? 輔助功能快捷鍵陪踩,之后選擇 VoiceOver。
這會(huì)創(chuàng)建一個(gè)快捷鍵悉抵,此時(shí)你可以連按三次 home 鍵或側(cè)面按鍵(全面屏的新設(shè)備沒有 home 鍵時(shí))膊毁,在一個(gè)真機(jī)上開關(guān) VoiceOver。
注意:在 VoiceOver 旁邊有很多其他的輔助功能基跑,包括反轉(zhuǎn)顏色、增加對(duì)比度描焰、色彩濾鏡媳否、降低白點(diǎn)值、縮放荆秦、切換控制等篱竭。在這個(gè)教程中,我們把精力主要放在 VoiceOver 上步绸。
現(xiàn)在你已經(jīng)啟動(dòng)了 VoiceOver掺逼,試一試吧。
如何使用 VoiceOver
VoiceOver 帶有一些方便的手勢(shì)預(yù)設(shè)瓤介,可以很輕松地瀏覽一個(gè)應(yīng)用吕喘。下面是一些常用的應(yīng)用內(nèi)使用 VoiceOver 的手勢(shì):
- 單擊屏幕上的任意位置,VoiceOver 會(huì)大聲念出項(xiàng)目的輔助功能屬性中的識(shí)別信息 (identifying information)刑桑。
- 向左或向右輕掃 (swipe)氯质,VoiceOver 會(huì)選擇下一個(gè)可視輔助功能項(xiàng)目并大聲念出該項(xiàng)目。右掃則向右向下移動(dòng)祠斧,左掃移動(dòng)方向相反闻察。
- 向下輕掃可以逐個(gè)地念出每個(gè)字母(或漢字、符號(hào)等)。
- 雙擊選中聚焦的項(xiàng)目辕漂。
- 三指輕掃呢灶,向左或向右輕掃,可以在不同頁面視圖間前進(jìn)或后退(譯者注:例如網(wǎng)頁的前進(jìn)后退钉嘹,或桌面左右滑動(dòng)等)
想要查看完整的 VoiceOver 手勢(shì)列表鸯乃,請(qǐng)?jiān)L問蘋果官方 VoiceOver 手勢(shì)手冊(cè)。好了隧期,現(xiàn)在你知道 VoiceOver 如何工作了飒责,但是你的 App 和 VoiceOver 一起使用會(huì)是什么樣的?我們?cè)谙乱徊街旭R上就會(huì)進(jìn)行測(cè)試仆潮。
在食譜應(yīng)用中嘗試 VoiceOver
在真機(jī)上構(gòu)建并運(yùn)行應(yīng)用宏蛉,之后連按三次 home 鍵啟動(dòng) VoiceOver。向左和向右輕掃以訪問食譜列表性置。VoiceOver 會(huì)從左上至右下讀取元素拾并。從頂部的標(biāo)題開始,然后是每個(gè)食譜的名稱和配圖的名稱鹏浅。
但是 VoiceOver 的使用體驗(yàn)有點(diǎn)問題:
- 圖像嗅义,每個(gè)單元格中的圖片描述都是這個(gè),這個(gè)描述可沒有太大作用隐砸。(譯者注:實(shí)際測(cè)試中之碗,iPhone X上系統(tǒng)可能會(huì)對(duì)圖片內(nèi)容自動(dòng)進(jìn)行識(shí)別并播報(bào),但更老的iPhone 5s中則只會(huì)播報(bào)“圖像”)
- VoiceOver 并沒有念出每個(gè)食譜的難度等級(jí)季希,所以這個(gè)特征對(duì)視障人士就失去了意義褪那。
現(xiàn)在我們已經(jīng)發(fā)現(xiàn)了一些問題,你可能想立刻解決這些問題式塌。但是在解決之前博敬,我們得先了解一點(diǎn)輔助功能的工作原理。
輔助功能屬性 (Accessibility Attributes)
要支持輔助功能峰尝,輔助功能屬性是必須要實(shí)現(xiàn)的核心部分偏窝。VoiceOver 讀取我們 App 中的元素信息,然后大聲念給用戶聽武学。如果輔助功能屬性沒有配置得當(dāng)祭往,VoiceOver 就不能念出我們應(yīng)用的必要細(xì)節(jié)。
一個(gè)輔助功能屬性 (attribute) 有5種內(nèi)容 (property):
- 標(biāo)簽(Label):一種簡(jiǎn)明的識(shí)別控件或視圖的方式劳淆。例如返回按鈕和食譜圖像链沼。
- 特性(Traits):特性描述了元素的狀態(tài)、行為或用法沛鸵。例如括勺,一個(gè)按鈕的特性可能是selected缆八。
- 提示(Hint):描述元素可以完成的動(dòng)作。例如:顯示食譜詳情疾捍。
-
尺寸(Frame):屏幕內(nèi)元素的
CGRect
格式尺寸奈辰。VoiceOver 會(huì)念出CGRect
的內(nèi)容。 - 值(Value):元素的值乱豆。例如奖恰,進(jìn)度條或者滑塊當(dāng)前的值可能會(huì)念為:百分之5。
大部分UIKit元素已經(jīng)把上面這些屬性為我們做好了宛裕;你只需要再改進(jìn)一些細(xì)節(jié)瑟啃,以提升用戶體驗(yàn)。如果我們創(chuàng)建了一個(gè)自定義的組件揩尸,大部分的屬性就得自己動(dòng)手設(shè)置了蛹屿。
注意:這個(gè)食譜App使用的是標(biāo)準(zhǔn)的UIKit視圖和控件,其中大部分輔助功能已經(jīng)啟用了岩榆,最多只需要我們修改一下屬性字符串就可以了错负。對(duì)于那些用自定義元素的工程,請(qǐng)確保已經(jīng)讀過了我們的 iOS Accessibility Tutorial: Making Custom Controls Accessible 教程勇边。
現(xiàn)在我們已經(jīng)搞清楚 VoiceOver 是從哪里為用戶獲取的信息了犹撒,是時(shí)候了解一下這個(gè)可以幫我們發(fā)現(xiàn)并修復(fù) App 中輔助功能缺陷的新工具了:Accessibility Inspector。
Accessibility Inspector 的使用
如果你正在改進(jìn)一款 App 的輔助功能粒褒,找出可改進(jìn)之處是一件既費(fèi)時(shí)又容易出錯(cuò)的工作识颊。幸運(yùn)的是,有一個(gè)叫做 Accessibility Inspector 的工具可以幫助我們奕坟,這個(gè)工具的功能如下:
- 貫穿我們的應(yīng)用整個(gè)運(yùn)行期間谊囚,找出輔助功能的常見問題。
- 讓我們可以在檢查模式下执赡,查看 UI 元素的輔助功能屬性。
- 無需離開我們的應(yīng)用函筋,即可進(jìn)行輔助功能元素的實(shí)時(shí)預(yù)覽沙合。
- 支持所有平臺(tái),包括 macOS跌帐、iOS首懈、watchOS 和 tvOS。
在食譜App上使用 Accessibility Inspector 之前谨敛,先來看一下這個(gè)工具究履。首先,在 Xcode 菜單欄中點(diǎn)擊 Xcode ? Open Developer Tool ? Accessibility Inspector 啟動(dòng)該工具脸狸。
這個(gè)檢查器工具看起來應(yīng)該是類似這樣的:
Target Chooser 可以選擇你想要進(jìn)行檢查的設(shè)備最仑∶臧常可以是你的 MacBook Pro、iOS 設(shè)備或者模擬器泥彤。
可以在模擬器中進(jìn)行輔助功能元素的實(shí)時(shí)預(yù)覽欲芹。因?yàn)閷?shí)時(shí)預(yù)覽比聽 VoiceOver 更快,所以這里是我們這篇教程的主戰(zhàn)場(chǎng)吟吝。
在模擬器中構(gòu)建并運(yùn)行 App菱父,然后把 Accessibility Inspector 的 target 修改為我們的模擬器:
現(xiàn)在我們已經(jīng)打開了這個(gè)工具,可以看一下它有哪些非常實(shí)用的功能剑逃。
Inspection Pointer 的使用
注意:撰寫本文時(shí)浙宜,最新版本的 Xcode 11.3 有個(gè) bug,使用這個(gè)工具的時(shí)候可靠性不是很好蛹磺。
選擇 Inspection Pointer粟瞬,就是界面中看起來像準(zhǔn)星標(biāo)志的按鈕,這個(gè)功能類似我們?cè)谡鏅C(jī)上開啟了 VoiceOver称开。當(dāng)我們開啟了這個(gè)功能亩钟,就可以把鼠標(biāo)指針懸停在任意 UI 元素上查看其屬性。直接使用鍵盤和模擬器交互時(shí)鳖轰,Inspection Pointer 不會(huì)起作用清酥。
Inspection Detail 面板中包含了所有我們需要查看并和 App 中的輔助功能屬性交互的內(nèi)容:
- Basic: 顯示當(dāng)前高亮元素的屬性內(nèi)容。
- Actions: 我們可以在這里執(zhí)行類似點(diǎn)擊按鈕蕴侣、滾動(dòng)視圖這樣的動(dòng)作焰轻。點(diǎn)擊這個(gè)面板中的 Perform 按鈕,會(huì)在設(shè)備上執(zhí)行某個(gè)動(dòng)作昆雀。
- Element: 顯示當(dāng)前元素的類辱志、內(nèi)存地址和視圖控制器。在撰寫本文時(shí)狞膘,這里有時(shí)候工作不太正常揩懒。
-
Hierarchy: 顯示元素的視圖層級(jí)樹,讓我們可以更容易地理解復(fù)雜的視圖關(guān)系挽封。
使用 Quicklook 檢查 Xcode 中的音頻
Xcode 11 在 Inspection Detail 面板中新增了一項(xiàng)功能已球,頂部的 Quicklook 里,我們可以在Xcode中聽到本該在設(shè)備上聽到的內(nèi)容辅愿。這意味著我們可以在沒有真機(jī)的情況下智亮,檢查用戶使用我們 App 時(shí)會(huì)聽到的內(nèi)容。
當(dāng) App 在模擬器中運(yùn)行時(shí)点待,點(diǎn)擊播放按鈕阔蛉,Accessibility Inspector 會(huì)循環(huán)念出 App 中每個(gè)元素的描述。
如果你喜歡手動(dòng)檢查每個(gè)元素癞埠,可以點(diǎn)擊 Quicklook 中的 暫停 按鈕或 喇叭 按鈕状原。點(diǎn)擊上一曲或下一曲按鈕聋呢,可以以你自己的節(jié)奏挨個(gè)檢查每個(gè)元素。
(譯者注:此處原文中有一張GIF動(dòng)圖遭笋,超出了簡(jiǎn)書圖片大小限制坝冕,可點(diǎn)擊超鏈接自行查看)
用這個(gè)功能,可比在真機(jī)上運(yùn)行 App 然后再用 VoiceOver 快多了瓦呼,特別是在開發(fā)階段喂窟。一如既往,你可能還是想在真機(jī)上測(cè)試 App 的所有輔助功能央串。
通過審計(jì) (Audit) 功能找出問題
Accessibility Inspector 中最有用的功能之一就是它的審計(jì)磨澡,它會(huì)給我們提示 App 輔助功能中的警告。來試一下這個(gè)功能质和,保持模擬器中的App正常運(yùn)行在食譜列表頁面稳摄。點(diǎn)擊 Audit 圖標(biāo),之后點(diǎn)擊 Run audit饲宿。
可以看到 Accessibility Inspector 給出了一些警告厦酬,包括我們有些元素沒有描述信息等。
點(diǎn)擊某個(gè)警告后瘫想,相關(guān)的元素會(huì)在模擬器中仗阅、審計(jì)頁面底部被高亮顯示。
在我們的這個(gè) App 中国夜,單元格中的圖像視圖沒有描述信息减噪。所以 VoiceOver 不能為我們的用戶播報(bào)圖像的描述。
點(diǎn)擊修改建議圖標(biāo)车吹,就是圓圈里面一個(gè)問號(hào)的圖標(biāo)筹裕,對(duì)于每個(gè)警告都會(huì)給出一個(gè)修改建議。稍后我們會(huì)根據(jù)這些建議做修改窄驹。
點(diǎn)擊眼睛圖標(biāo)會(huì)為應(yīng)用截圖朝卒。這對(duì)于需要?jiǎng)?chuàng)建準(zhǔn)確的 bug 報(bào)告的測(cè)試人員很有用。
Accessibility Inspector 中還有一些實(shí)用的輔助功能設(shè)置乐埠。下面扎运,我們來快速瀏覽一下這些功能。
額外的 Accessibility Inspector 設(shè)置
盡管這超出了這篇教程的范圍饮戳,但是對(duì)于加深 Accessibility Inspector 的了解是有幫助的,我們可以測(cè)試下面的輔助功能設(shè)置:
- 反轉(zhuǎn)顏色
- 增強(qiáng)對(duì)比度
- 減弱透明度
- 減弱動(dòng)態(tài)效果
- 修改字號(hào)
不用再使用設(shè)置App去開啟這些功能洞拨。Accessibility Inspector 現(xiàn)在只有這5種設(shè)置扯罐,但是蘋果計(jì)劃在未來添加更多設(shè)置。
Accessibility Inspector 可以為你測(cè)試應(yīng)用節(jié)省時(shí)間烦衣。但是請(qǐng)記住歹河,你還是應(yīng)該手動(dòng)地使用 VoiceOver 測(cè)試一下實(shí)際的用戶體驗(yàn)如何掩浙。最后這一步可以幫你找出所有 Accessibility Inspector 沒發(fā)現(xiàn)的問題。
現(xiàn)在我們已經(jīng)了解了 Accessibility Inspector 的功能秸歧,接下來改造一下我們的 App 吧厨姚。
讓食譜 App 更好用
在我們之前使用 VoiceOver 測(cè)試這個(gè) App 的時(shí)候,你應(yīng)該還記得圖像的描述信息沒太大用處键菱。audit 工具已經(jīng)提示了原因:image view 沒有輔助功能標(biāo)簽谬墙。我們現(xiàn)在來修復(fù)一下。
在 Xcode 中打開 RecipeCell.swift经备,在文件底部增加下列代碼:
// MARK: Accessibility
extension RecipeCell {
func applyAccessibility(_ recipe: Recipe) {
// 1
foodImageView.accessibilityTraits = .image
// 2
foodImageView.accessibilityLabel = recipe.photoDescription
}
}
上面的代碼基于單元格的Recipe
對(duì)象補(bǔ)充了缺失的輔助功能屬性拭抬。下面是它的原理:
-
accessibilityTraits
屬性的設(shè)置,覆蓋了輔助功能元素之前的類型特征侵蒙。在這里造虎,.image
表示他是一個(gè)圖像。 - 在 VoiceOver 中會(huì)使用
accessibilityLabel
中的內(nèi)容去描述這個(gè)元素纷闺。這里我們把他設(shè)置成了recipe.photoDescription
算凿,這是一個(gè)圖片的內(nèi)容描述字符串。
現(xiàn)在犁功,我們想要把這種設(shè)置同樣應(yīng)用到其他食譜單元格中氓轰。找到RecipeCell
類中的configureCell(_:)
。在方法的最后增加下面這行內(nèi)容:
applyAccessibility(recipe)
每次創(chuàng)建一個(gè)新單元格波桩,這行代碼都會(huì)把 recipe 對(duì)象中的相關(guān)信息設(shè)置到輔助功能屬性中戒努。
在真機(jī)上構(gòu)建并運(yùn)行 App,連續(xù)點(diǎn)擊3次 home 鍵啟動(dòng) VoiceOver镐躲。測(cè)試一下菜單列表的圖像描述是不是更加有意義了储玫。
(譯者注:原文中此處有YouTube視頻,科學(xué)上網(wǎng)萤皂,自行查看)
好多了撒穷!相比簡(jiǎn)單地聽到“圖像”二字,可以聽到圖像的完整描述了●晌酰現(xiàn)在用戶可以更加形象地想象出食物端礼,而不是因?yàn)椴恢缊D像上是什么而感到沮喪。
在模擬器中運(yùn)行這個(gè) App入录,再次打開 Accessibility Inspector 并進(jìn)入食譜列表蛤奥。清空所有警告,然后點(diǎn)擊 Run Audit僚稿。
哇塞~沒有描述信息的警告了耶凡桥!成功地為圖像添加描述之后,這個(gè)視圖的核心內(nèi)容已經(jīng)可以被完全訪問了蚀同。
現(xiàn)在缅刽,是時(shí)候讓食譜的難度等級(jí)變得更加易于訪問了啊掏。
轉(zhuǎn)換難度標(biāo)簽
在 Accessibility Inspector 里,我們已經(jīng)注意到了有一種警告是 potentially inaccessible text(可能無法訪問的文本)衰猛,也就是說難度標(biāo)簽對(duì)于視力受損的用戶是不可見的(譯者注:難度標(biāo)簽??看起來像是圖片迟蜜,實(shí)際是 emoji 表情,本質(zhì)上是文本)啡省。怎么修復(fù)這些警告呢娜睛?我們得讓這些標(biāo)簽更加易于訪問,并且要用更加有意義的描述去更新標(biāo)簽的輔助功能屬性冕杠。
下一步微姊,到 RecipeCell.swift 文件中,在applyAccessibility(_:)
方法的最后增加下面的代碼:
// 1
difficultyLabel.isAccessibilityElement = true
// 2
difficultyLabel.accessibilityTraits = .none
// 3
difficultyLabel.accessibilityLabel = "Difficulty Level"
// 4
switch recipe.difficulty {
case .unknown:
difficultyLabel.accessibilityValue = "Unknown"
case .rating(let value):
difficultyLabel.accessibilityValue = "\(value)"
}
下面是代碼的解釋:
-
isAccessibilityElement
是一個(gè)標(biāo)志分预,為true
時(shí)會(huì)讓這個(gè)元素對(duì)于輔助功能來說是可見的兢交。對(duì)于大多數(shù) UIKit 類,默認(rèn)為true
笼痹,但是 UILabel 的是false
配喳。 -
accessibilityTraits
幫助標(biāo)識(shí)輔助功能元素的特征。因?yàn)檫@個(gè)標(biāo)簽不需要任何交互凳干,所以設(shè)置為了none晴裹。 - 之后,我們的 VoiceOver 就可以簡(jiǎn)明地識(shí)別出標(biāo)簽的含義了救赐。
Difficulty Level
可以讓用戶清楚地知道他們?cè)谧龅氖澄锸鞘裁措y度涧团。 - VoiceOver 會(huì)把
accessibilityValue
作為標(biāo)簽描述的一部分念出來。在這里設(shè)置好難度等級(jí)可以讓這個(gè)元素變得更有幫助经磅。
在真機(jī)上構(gòu)建并運(yùn)行 App泌绣,三擊 home 鍵打開 VoiceOver,輕掃以收聽整個(gè)食譜列表的播報(bào)预厌。
(譯者注:原文中此處有YouTube視頻阿迈,科學(xué)上網(wǎng),自行查看)
當(dāng)我們掃過不同的輔助功能元素時(shí)轧叽,VoiceOver 會(huì)念出每個(gè)單元格的完整描述苗沧,包括難度等級(jí)。
檢查警告
每次暴露一個(gè)新的輔助功能元素后炭晒,就像我們剛剛對(duì)難度等級(jí)做的處理待逞,都應(yīng)該重新運(yùn)行一下審計(jì) (audit)。
如果 Accessibility Inspector 沒啟動(dòng)网严,先把它打開识樱。在真機(jī)或者模擬器運(yùn)行我們的 App,并設(shè)置好相應(yīng)的檢查 target。現(xiàn)在點(diǎn)擊 audit 按鈕然后點(diǎn)擊 Run audit牺荠。
警告變少了!僅存的一種警告是標(biāo)簽不支持動(dòng)態(tài)文字(字號(hào))驴一。我們接下來會(huì)修復(fù)這個(gè)問題休雌。
支持動(dòng)態(tài)文字(字號(hào))
警告中明確提示了我們?nèi)鄙僖粋€(gè)讓App對(duì)每個(gè)人都可用的重要步驟:動(dòng)態(tài)文字(dynamic text)。這是一個(gè)輔助功能中的重要特性肝断,可以讓視力部分受損的用戶加大字號(hào)杈曲,讓文字更容易看清。我們現(xiàn)在的App使用了非動(dòng)態(tài)的字體胸懈,導(dǎo)致用戶不能使用這項(xiàng)功能担扑。
點(diǎn)擊 Fix Suggestions 圖標(biāo),查看修改建議是什么:
建議里面說我們應(yīng)該考慮用 UIFont 推薦字體 (preferred font)趣钱,并把
adjustsFontForContentSizeCategory
設(shè)為true∮肯祝現(xiàn)在就來動(dòng)手吧。
在 RecipeCell.swift 文件的applyAccessibility(_:)
最底部增加下面的代碼:
dishNameLabel.font = .preferredFont(forTextStyle: .body)
dishNameLabel.adjustsFontForContentSizeCategory = true
difficultyLabel.font = .preferredFont(forTextStyle: .body)
difficultyLabel.adjustsFontForContentSizeCategory = true
這里把preferredFont
設(shè)置為body
風(fēng)格首有,也就是說 iOS 會(huì)把文字顯示為文檔主體內(nèi)容的字體風(fēng)格燕垃。具體字號(hào)和字體取決于輔助功能設(shè)置。adjustsFontForContentSizeCategory
表示當(dāng)用戶修改了文本內(nèi)容尺寸時(shí)井联,是否應(yīng)該自動(dòng)更新字體卜壕。
感謝 Accessibility Inspector,測(cè)試 App 如何處理字號(hào)變化非常簡(jiǎn)單烙常。
構(gòu)建并運(yùn)行食譜 App轴捎,打開 Accessibility Inspector。再次運(yùn)行審計(jì)后所有警告應(yīng)該都消失了蚕脏。
測(cè)試其他設(shè)置項(xiàng)
進(jìn)入 Accessibility Inspector 的設(shè)置頁面侦副,嘗試一下其他的工具:
- Invert Colors,看一下你的應(yīng)用是什么樣吧蝗锥。這個(gè)對(duì)那些有光敏感跃洛、弱視和某些情況下色盲的人很有用。
- 你也可以為那些喜歡更大字體的用戶測(cè)試一下實(shí)時(shí)修改動(dòng)態(tài)字體大小终议。
測(cè)試我們的App時(shí)汇竭,看起來應(yīng)該是這樣的:
Accessibility Inspector 使得測(cè)試輔助功能變得很容易。至此穴张,我們可以說食譜列表能為那些視力受損的用戶很好地工作了细燎。
轉(zhuǎn)換食譜詳情頁面
現(xiàn)在我們已經(jīng)處理好了食譜列表,再來看看用戶點(diǎn)擊某個(gè)食譜之后是什么樣的吧皂甘。在設(shè)備上運(yùn)行 App玻驻,打開 VoiceOver,看看詳情視圖。聽起來是這樣的:
(譯者注:原文中此處有YouTube視頻璧瞬,科學(xué)上網(wǎng)户辫,自行查看)
在詳情頁面用VoiceOver交互有些問題:
- 左箭頭按鈕對(duì)于導(dǎo)航返回按鈕來說不是個(gè)很好的描述。用戶怎么會(huì)知道這個(gè)按鈕是干什么的呢嗤锉?
- emoji 表情狀態(tài)是:心型眼的表情和困惑的表情渔欢。這種解釋會(huì)讓所有用戶都感到懵圈!
- 當(dāng)用戶選擇了一個(gè)復(fù)選框瘟忱,會(huì)聽到 icon empty奥额,這個(gè)解釋性不是很好。
上面的問題中访诱,解釋控件狀態(tài)的含義是很重要的垫挨,而不是控件看起來是什么樣子。返回按鈕比左箭頭按鈕聽起來更明了触菜。喜歡和不喜歡可以很簡(jiǎn)潔地解釋 emoji 表情九榔。下面我們就來修改這兩個(gè)問題。
修改導(dǎo)航欄返回按鈕玫氢,打開 RecipeInstructionsViewController.swift 并在viewDidLoad
中的assert(recipe != nil)
后面添加下面的代碼:
backButton.accessibilityLabel = "back"
backButton.accessibilityTraits = .button
現(xiàn)在 VoiceOver 不會(huì)再說左箭頭按鈕帚屉,而是返回(back)按鈕。
再來看看 emoji 表情漾峡。還是這個(gè)文件中攻旦,用下面的代碼替換掉isLikedFood(_:)
中的內(nèi)容:
if liked {
likeButton.setTitle("??", for: .normal)
likeButton.accessibilityLabel = "Like"
likeButton.accessibilityTraits = .button
didLikeFood = true
} else {
likeButton.setTitle("??", for: .normal)
likeButton.accessibilityLabel = "Dislike"
likeButton.accessibilityTraits = .button
didLikeFood = false
}
為喜歡和不喜歡模式添加了一個(gè)accessibilityLabel
,這樣按鈕的功能就更明確了生逸。我們還把accessibilityTraits
設(shè)置為了按鈕牢屋,這樣用戶就知道怎么和這個(gè) emoji 表情進(jìn)行交互了。
在設(shè)備上構(gòu)建運(yùn)行并啟動(dòng) VoiceOver槽袄。進(jìn)入食譜詳情頁面缔俄,用 VoiceOver 測(cè)試一下我們對(duì)視圖頂部的按鈕所作的修改撒会。
(譯者注:原文中此處有YouTube視頻叹阔,科學(xué)上網(wǎng)蔓同,自行查看)
現(xiàn)在,每個(gè)功能都清晰明確了乾戏,簡(jiǎn)潔的描述可以幫助用戶理解這些功能的含義迂苛。好多了!
改進(jìn)復(fù)選框
最后的問題是列表清單鼓择。對(duì)于每個(gè)復(fù)選框三幻,VoiceOver 現(xiàn)在會(huì)念出 icon empty 然后念出食譜的制作方法。這一點(diǎn)都不清晰明了呐能!
來修改一下念搬,打開 InstructionCell.swift 然后找到shouldStrikeThroughText(_:)
。把if strikeThrough
代碼塊的所有內(nèi)容替換為下列內(nèi)容:
// 1
checkmarkButton.isAccessibilityElement = false
if strikeThrough {
// 2
descriptionLabel.accessibilityLabel = "Completed: \(text)"
attributeString.addAttribute(
NSAttributedString.Key.strikethroughStyle,
value: 2,
range: NSRange(text.startIndex..., in: text))
} else {
// 3
descriptionLabel.accessibilityLabel = "Uncompleted: \(text)"
}
這些代碼做了什么:
- 把復(fù)選框按鈕的輔助功能關(guān)掉,這樣VoiceOver就可以把復(fù)選框和后面的文字當(dāng)成一個(gè)整體朗徊,而不是兩個(gè)不同的輔助功能元素首妖。
- 現(xiàn)在
accessibilityLabel
的描述信息使用硬編碼的"Completed"
后面接上制作方法文本。這樣就把一個(gè)帶復(fù)選框狀態(tài)和標(biāo)簽內(nèi)容的所有必要的信息都提供出來了爷恳。 - 和已完成的代碼一樣悯搔,如果用戶把一個(gè)條目標(biāo)記為未完成,就在標(biāo)簽描述前面增加
Uncomplete
舌仍。
再次構(gòu)建運(yùn)行 App,然后聽一下播報(bào)通危。對(duì)用戶來說這簡(jiǎn)直像美妙的音樂一樣??
(譯者注:原文中此處有YouTube視頻铸豁,科學(xué)上網(wǎng),自行查看)
接下來呢菊碟?
你可以在文章開頭下載到工程的完整代碼节芥。
在這篇 iOS accessibility 教程中,你學(xué)到了 VoiceOver 相關(guān)的內(nèi)容逆害。通過挨個(gè)元素播報(bào)內(nèi)容的收聽和親自進(jìn)行的用戶體驗(yàn)的測(cè)試头镊,我們執(zhí)行了手動(dòng)的檢查。之后魄幕,我們又用 Accessibility Inspector 執(zhí)行自動(dòng)審計(jì) (audit)相艇,看到了輔助功能元素的值,并操作了實(shí)時(shí)動(dòng)態(tài)修改反轉(zhuǎn)顏色纯陨、修改字號(hào)坛芽。
現(xiàn)在,你已經(jīng)學(xué)會(huì)了如何讓你的 App 更加好用翼抠。你將對(duì)某個(gè)人的生活產(chǎn)生積極的影響咙轩。
輔助功能還有很多內(nèi)容。這篇教程只是幫助你入門阴颖。下面是更多參考資料:
- Categories of Accessibility
- Accessibility Development Resources
- Applying Accessibility to Custom Views
- Deliver an Exceptional Accessibility Experience
- Accessibility Inspector
如果有任何疑問或指教活喊,在下面留言吧!
[The End]