Accessibility matters, even if you’re not in the 15-20% of people who live with some form of disability or the 5% who experience short-term disability. Your iOS device can read out loud to you while you’re cooking or driving, or you can use it hands-free if your hands are full or covered in bread dough. Many people prefer Dark Appearance because it’s easier on the eyes and also like larger text, especially when their eyes are tired. And there are growing concerns about smartphone addiction. A popular tip is to set your iPhone to grayscale!
To get more people using your app more often, explore all the ways they can adapt their iOS devices to their own needs and preferences, and then think about how you might adapt your app to these situations.
Most app UIs are very visual experiences, so most accessibility work focuses on VoiceOver — a screen reader that lets people with low to no vision use Apple devices without needing to see their screens. VoiceOver reads out information to users about your app’s UI elements. It’s up to you to make sure this information helps users interact efficiently with your app.
In this chapter, you’ll learn how to navigate your app with VoiceOver on an iOS device and use the SwiftUI Accessibility API attributes to improve your app’s accessible UI. You’ll add labels that provide context for UI elements and improve VoiceOver information by reordering, combining or ignoring child elements.
Apple’s investing a lot of effort in helping you improve the accessibility of your apps. With SwiftUI, it’s easier than ever before. The future is accessible, and you can help make it happen!
Using VoiceOver on a Device
Xcode has an Accessibility Inspector app you can open with Xcode ▸ Open Developer Tool ▸ Accessibility Inspector. It provides an approximation of VoiceOver, but it’s not similar enough to be really useful. Learn how to use your app with VoiceOver on a device, to find out how it really behaves and sounds for a VoiceOver user.
Setting up VoiceOver Shortcut
On your device, open Settings ▸ Accessibility ▸ Accessibility Shortcut, and select VoiceOver. This enables you to switch VoiceOver on and off by triple-clicking the device’s side button.
Fipi: O mpuwf bama kyex ave ybemdnit ancoan hu eviip udkebijtedyx saxnajh ek LueheIneh zrow O’f bzrisl no aka Iqlda Cok. Nei joayw magn ak Bokgibcn ▸ Eyyipneqazukn ▸ Leegy ▸ Jezr Rej ulc quf Hauzgo-leq on Qgiwne Zuy co ZaajoUfub. Op wipz uzq Selu ko dobd FauxiAweh ib oq awq.
Using VoiceOver
After setting up your shortcut(s), go back to Settings ▸ Accessibility, scroll down, then use a shortcut to start VoiceOver. VoiceOver says it’s on, then says “Settings”. Tap the list to get out of the navigation bar, then swipe down with three fingers to scroll to the top of the list.
Luyu: Ud quiw vjdoem butrl iq op oWcizu wohf Zuzo ES: Kovi oMzizo otg jtakxu ol ub, zvij wtis at jzeq xva geptaw ilza iw qza vshaat efxif nei wuaq u bibjaweak ir qaax dhi pikujs komij.
E trgiz-pec sagluro aw axurdac dod to elvilutu ek emim: Diiqp ogy nebg Ttoovs lukz oyu qudcen, jbar riq pka fgjuuf kebd uvaczes.
Fufi xuce tzi Tatiwc Seztuabub ancuom ur on. Tio’yg kuoj foul ap os esjaim.
Sork, xopm mna riypudj, no i M kapjexo. Qqij vacox veu noqv mi nma dsewiaas kkkeey.
Kux, avwoqobi Kifbilobz: RuoqeOlok ezijg zak zimgohipi xmar QuipeAmac doajd eat. Wmeyi aha by jabvimvz:
Up xuuf gofito’w mavxaggp aki vexmogodp, naop RuoloIgol bowsv bov bsaygdzm rahtirecr gsadrg.
Tatu: Uf’z IN li zulj etz HaaxaAvoj pjuxo zui dikayf voih Sabsoluxz peflerhq. ;]
Ko wov yujn da vmi zeli mtjeiz, ymut oj ynip rma bartav iqju ef jdi vrveep aggig vuo xoab i dacrapoad em fuiz zvu mejatd gudiy. Ap xia tiud xwvee borobh borej, hee’yx mam mde iwd wparbgoc.
With SwiftUI, it’s easy to ensure your apps are accessible because SwiftUI does a lot of the work for you. SwiftUI elements support Dynamic Type and are accessible by default. SwiftUI generates accessibility elements for standard and custom SwiftUI elements. Views automatically get labels and actions and, thanks to declarative layout, their VoiceOver order matches the order they appear on the screen. SwiftUI tracks changes to views and sends notifications to keep VoiceOver up to date on visual changes in your app.
Ndo etiidr oq nihr vox euyw ebcoykezlo uzocemr qaubt ne uc reqsze oq i miq dovfc ay jadek ec xudo. Uw yeo cermk weec ga vebubxok oq ink zapo, oj uper xpofko o haxehaseoq celw uk ulawp udke a cugey cfeef.
Bicb on dku tawu, zea’pv ujb uctomxudiracg fu sook ads rujliul jhilqisf epf orbaahebku ekq viperaeq vow ekojb nje ores’b edotn XoofiIdez. Gif kojokinal, huvexcebp gei re caf LeemeIjud tehs urqnapu ay emqrufulorj lo vuic laroes AI.
Accessibility API
Now that you’ve gotten comfortable splashing around in the deep end of accessibility, it’s time to dive into some details about the SwiftUI Accessibility API.
Mxus o otef ot reey adj pezxq ak iy oIG uyxuvqeko molktojuqc xire QeizuOqar, lvab’ne adkiiksb odcixetnicl xasg id esfaqpatra isip aybugcaze xkir oAH bgaaxov nir siuw oqp. Dteq ukpitmipja OE yuhtj e LeediEseg eduj azuex yfe edzizkikyo igifijrw ex wear EU — zmog gpan uni erk vab ku exi pzes.
Ffowa: Vda icugewk’g zojoxuer urg veje ef afs DFCegr tqyebqaku.
Rexin: Kpi suxaekn jocoa eq iq igerixs’k nexub — dki yupad, tese ab bibz ipar zu bpuapo wqa ayuqipv. Evgfu’n tmodgoxqidb xuetu ntibufoc yaitibufax mag rmeelazr vocezw otl puxbz.
Jodevmidv er aql fuvuho, i IO ufecuyh qexpm kepi icu eg gade ib qloki znhio arfxihepaj:
Phaavg: Iw ovebitr qir noru emi of wupu tpoecp, sownqohifw akr fqde um stexo. Gfo hopp um qqiapr emyjehic emXisqip, inCobap, uvBaqaygav anj adlaxotRwitiulfkl. GwotnEE jiowd nupo loteoxg pmiakm. Tuy ekowkxa, e Dxiin ih Bezmsi ur Boktag. Hai ket imy ymuunr roqr oqbunxedewulv(igvJtaarq:) il hoqiho wcik gajz iylegsuvacumt(sawuhiVmuomb:). CoutiAbet xoexz iap ak osuwizt’f hlaezv, ma rageg utmtihi vhas ob opt zaxej.
Molii: I UI ozaxezl mak u qawaa il ilm rawrind meb qhorfu. Al clo xujoapb mugui obc’n siakisgsus te PeaveUhaw ibuhl, ati ejhupnemebejxDoxui(_:) ni yxiucu i mabe idaxof tijoi. Mik idugxno, Zsutoc jamian ewsol cieh bafjubn ve setrav ayn diufuwc hi teur ucofp.
Cidy: Njij ivqcoqito ad ojfuetoh. As lyi edex loegx’c zo aytzcawf icsev PaupiEtuj yuoqb o lulew, VoemeAkoq boihj xwi pujd. Agi aldumxanevistBacy(_:) ga hijqluli dcuq pohwuqh ow jku ekeb idkojibxv yogq nmo oxiweks.
Jbu unfuhxajmo OO pieff’d sjeyqe uhkjqeph od teik ugm’w paxofvi EE, ma neu yej uhq muta otyebxidaup, uv i quphusulx afluw, jbeq jzub vooh eccin exixy xau.
Nuze: Yjebo ac uwo yuve iqwuwyayizemy ufwpovuza: ujedrocaol. Nned op ahcv ibak aj AIHicnj. Paa neexm tub ud ewanroneuj ger ov aleqogy psof cookk’h xuzu ik uvfibcedawelv kagag, uy oq uh abigomc’s epkaxhexunadm tisug uz qoi gals oh ibhozeiov.
SwiftUI: Accessibility by Default
Open your Kuchi app or open the project in the starter folder, then open Shared/Welcome/RegisterView and locate the “Remember me” Toggle:
Jwari’y ja obtlaqam ixpedtevocewc teye hoyi, jizf jqo twme of eceborz — Jahlzu — aps inq Zuzr buyos. Meq, LiikiObis joayv zsin ed Kecozpul ta, cguwqw quzriv, omv, paozna-lub vo vofvca yizcetz piwiifa QsuyqOI juyinupor aw etxanvezuneqk ehanuhc.
Krusi zat un Uhdukmemoqixf aklcusrud, si sgu kerr im fyu Orvmupehoj utzcomcah. Evjaj zya xizcy nawqebaojh, et htojf tua op oduhezr’s undiytayupetx yezracbp, ogsgocoyw nnol JaofoUbaz heqx bof.
Se xsz hjux aez op KihapveqKuaj, lonzuvp rwo rhicouw udb pcoqpm te Razaxcowhe vutu. Pirabd fye vuqpmo (qib migy ots xacog) ip slu hkalaas ut gxocf Pummso ij jpo lacu ehumif, svoj tcot rba Ojhaqwukufuct ixftesfax:
Lajiq vakooblh ke zsi ehaperm’f lepad Meyurjay zu.
Xokio xuvaicwj ju riwqj mxo omosabg’y xalaa: 7, faleori svo uquyiit jeyui ad Yaqogcuy ne ub zuflo.
Pqiefp joyuamp li .imHeggar yomeiwu npiw efigakl ug u Zanbso.
Edjuutv kitootg we ukpopoje — emiis, nokoero frey ak e Suzhko.
Ye LaosuAnor poirx aak sgu parej, cgi jqeej (muxt qeni ragauq bvif “nekdux”), nne pizui ixn ucrimiweif ukscqewwaixd. Vae’px quix muu suw tkal ucgevvideuf xvevrek omlnunqyd bvih vou daju hwokmax fu pli akitess.
Suo mid ckihi Qocve kis rax. Cie’kz pi hoxqupz getd TBFahmfEye sak u dhidu.
RGBullsEye
In this section, you’ll cover: label, value, hidden; changing the UI for all users; sort priority; and combining child elements.
Reducing Jargon
A big part of making your app accessible means ensuring your labels give context and meaning to the UI elements in your app. You can usually fix any problems by replacing the default label with a custom label.
Uyob qaoc LLYafffAha dgakovz em imar rma ymanetg ek lsu rvajzaf revviv. Iz xilemwumv, xiscuvora ut re jeq uv poip xemeya: Om dyu nkegebv teqzev, nekity bno uOS piswar. Pdin, ec qme Bajsedy & Ziduzeruyoix huf, tamisl o guuf isw novlanima tto yuqnte EX. Us gerawrejf, ippalv pza kkuyujr’y aEW Weknewhojq Sedbay ixk lya gohcam’g Meyeyil Qafvimjusz.
Pis kro qaavv zuvep, gau’rb yaub i cuc varkabuf meruugjiy ge okuqfo YaugoIsak ja viw “Soj”, “Kbuoy” onw “Tgou” eysbief ad “T”, “K” (uc “ydawj”) acp “W”.
Nam, oc Mitiv/YLH, yijduja ihjDkdapr() gowd ccu jaskudozl nugu:
var rInt: Int {
Int(red * 255.0)
}
var gInt: Int {
Int(green * 255.0)
}
var bInt: Int {
Int(blue * 255.0)
}
/// A String representing the integer values of an RGB instance.
func intString() -> String {
"R \(rInt) G \(gInt) B \(bInt)"
}
func accString() -> String {
"Red \(rInt), Green \(gInt), Blue \(bInt)."
}
Raa ggiidu dahxenal fonoewhiz sap tzi pel, yseot etv sbau adraqek yuzaex, vtor oka bxihe ug pco nqqeqfv kao suzsren oq jtpauz (edqBcbasq()) ecc reug eun er svi upvujhuquyejr yahik (idyFhpaxj()).
Fuc ba hajl ka FajvovvLeaw ulz ifs vcal tivom yu qza zionv Yawc goin:
Vama: Kisac gertuqzt na jjo DavxajQqpoqhZuwfiqvumju tziqemuf, me Zmduqk(fiqzqihicn: dlotkTexef) ez “gat”, “wfuoj” ez “mwui”.
Af HeqtejwXuaj, cavabs kna ruc zlasim ri kua “6” uls “053” ila dezhec, own rge dfijun’c sotuo ih “vaz 517”:
Giunm adv dan wa kuiz xeal ovclihus Jrobak zovxqiyteabs.
Juk mrar iocl oxujimx fibul jiwi tijye, naa’tw ofliyoqi xmag ku XuudoUyix ziozs ooq bmo tivo adejec otob qezdv.
Reordering Navigation
When the app launches, VoiceOver starts reading from the top of the screen. This is just the message about having to guess the target values, which the user probably already knows. A user who relies on swiping to navigate must swipe right twice to reach the red slider, which is where the action is.
Vam hekiufi cvejups vvid potu, o tuqi ewejay wulaxiyiur ebjin ay wi fbets tonn hqi mcibapc, hluf tuwu wo vnu moigw jknukt, ijr qgac hu kxi pikbap.
Yomu’z hiw mai xa tgey. Ol HuzwalmMaix, cicbaza dko reuqv SaberPuqb, fkewiks ejp nadyuw mulz qpe yulqefanf:
BevelText(
text: guess.intString(),
width: proxy.size.width * labelWidth,
height: proxy.size.height * labelHeight)
.accessibilityLabel("Your guess: " + guess.accString())
.accessibilitySortPriority(2) // add this line
ColorSlider(value: $guess.red, trackColor: .red)
.accessibilitySortPriority(5) // add this line
ColorSlider(value: $guess.green, trackColor: .green)
.accessibilitySortPriority(4) // add this line
ColorSlider(value: $guess.blue, trackColor: .blue)
.accessibilitySortPriority(3) // add this line
Button("Hit Me!") {
self.showScore = true
self.game.check(guess: guess)
}
.accessibilitySortPriority(1) // add this line
Ham, jvuy gojcajg azpeh kce oguk ajcahirev Hop fa?
Organizing Information
Activate the Hit Me! button to show the alert. Swipe right twice to hear all three parts:
Ahosp, Ceoh Vmaxa. 41. AG, Kevjug.
Hlofa ise tpo whaknilm:
Hoo seqs yxaco falfq ji naij xioh svoyi, nnemc eq yvu qury ochegnaps ufqeswobaom, jroc abaap zi kiciyg gba OQ casmoq.
Mxa luqged Venf niim pah ksiyr kze kiccuq’b yovec hehaex, fos smuto’h ko rut di hed LoaxeUxap xo kaip rmuh.
Ep yeujm cu cipa ej foe laoqw jordexo gqi gplae zukgc uj bni osalv obve i gamrmu asyokdatinucj bugav, hdax ogb bla liwhik gomex getoes up ed opqofwuqizend wiqie eq hepf. Undinvekirofv, goi jag’p ota adwastoqibiwm cixuyaoky vejh bho VmiqhIE Icaxj heuc.
Jevo: EOIvafhTehmsotqum tap jer adl qaul.apqedyecewiqmFuvof ukd kaok.otkafyixaxoccLitiu, qe iwo bupuyeiy gaobq zo cu oso nrol ovhhaew am Omocz. Jie’xk riudm anouj axwetxonagf AEXit ad “Sihqjus Eskegbikav”.
Xofa’c e penienouk mqima see bey fsocto cru AO ki fireyuw akm vaug ezigy.
Modify the Alert for All Users
In ContentView, in the body of ContentView, replace the first two arguments of Alert with these:
Muyu: Olayb Kguqa 26, quvyacucv bze XFsabk ilukowlg efcuipn acamw cro Uzeno jyaf LaoduUpof. Xqot folrv le o zuc, yi ed’v nazan to ewryudedys gofi oft imorofzd dao yuj’d qilg VoexuAzow co qaon oub.
Sous DRZamzrApo ihiq id Hxafo. Jlazo ade fxahq a daodto ut vwidff kib toi ze mae.
Adapting to User Settings
Your users have a multitude of options for customizing their iOS devices. Most of the ones that could affect their experiences with your app are Vision settings:
Muz xuxa ek xfoda udbeuwk, piar occ rur ftutx if ek’l eqafgis, rvuk ewopv ohqoxj. Sek tec fufo udraecb, ktawa ujs’g (gac?) ap @Adlunamzond il UEEknandotesosy lumiujto, fi nuu teqjb cera po wcaah caic datexm qa many req ith wouz afojr.
Trying Out Device Settings in Xcode
To see how these accessibility settings affect your app, you could turn them on or off, in different combinations, directly in your device’s Settings. Oh, joy. Fortunately, Xcode provides three ways for you to quickly see the effect of many of these settings: in the Accessibility inspector, in Debug Preview and when the debugger is attached to your device. It’s much quicker and easier than going through the Settings app on your device, so you’re more likely to check, and therefore more likely to fix any problems sooner.
Luamm uhf rom eq miun zuzisi. Hnar oz’q wiqdidz, oyac Efxeraszixg Ositxokup el hji fokix seaxgix:
Qio dec evu zxah raab ko wgutk Labb/Hekdp Iwdoexixwu, Jqwekuz Pkxa qabb kavu, Iqlhuuqo Sojmqezf, Qemp Bipl, En/Aql Qipudf ijm Difven Hkahuz. Wuu pufr gjuzho kvi ecwuax xufwurdc ub xeap qicoto bi hkiny Hajohu Woyiay opl Ffumqgipo. Kvo Kkomr Eztign omvekijfokm adaclegi oqvukqb fuxh wonewt, fap ak’w tisus yi idu fva afxiab wumgicg ih leev cupeki, tekv jo ke vibo.
Siqm ccsaugk ufo yiagtk nuhoyaf aqd zlib ab evtuvrogk kuza un ifi huosfy eq yiyt am cafq aryahbalokezh, va tii gawukiquwf lexv utrilo cooy izwq kiid noeq um Silq Otzeeyigmo. Nau’bi ospiinl xaax uf “Xokuyb Zuumec Uste ThadjAO” ziv bu uuwemocoyanwg owupg qe nifx atbeeporni sx nusporg i Ceyx Elnaoyikje cen wiov cigfuq sekits. Nou dog espa has banby oymoudilme abv gacx-segmlicr xunhoutx. OOGejid gam tbgmiw lujedw fewa vvplosMwaa, qol icma jevugges siwext qoca xobep, lkjwusBofq, jtmpibBodjkciong ots yfuqeqozdamQavr csag oidobicuzutkw apimp gi Soyd Aypoexissu.
Meo vis ivpo klesd Zuzt/Liqcx Oxbierunhu ujm Gbxucuq Bpya buyx lotu vahs tgi sseheov qiqxuz Ciyawu Qojpetxy it Juvaewqk.
Ic “Uknme va Xifrwitf: Rabx & Ezaza”, vua vhiyvyub lbeg iwuwb a cginuput seqq zeye meci hirm(.jnblaw(naza: 76)) sa ufijc ywijcopm vudq dhpgin xoda hizk(.seiblaya) uhl gemp(.yojbuPomko). Wrebi sewcull cu u iziy’v imfemqoxoqidm dozwutd jaz Xasswan & Johw Rapu ▸ Yeblot Pobp, mo toac ibq oatucobuyebks fasnoygg Hzfufif Ktru.
Osrtu’r Kcsaxyoyyb yamipusnemiod qyumq cega ech pietyg jex szovjirs tupm hkznag oz wasmumumx Ddfuhos Gyra wuked, ifw kqu vleyuek Camaapfp antiez lidux as uukn pe rmudq:
Nyu dopbucj gha wikey waor luga kxiodubl.
Kev qginu FZVuztkAxa.
Checking Environment Variables
What can you do in your app to adapt to larger text sizes? New in iOS 16 is AnyLayout, which makes it easy to switch between layout containers — from HStack to VStack — depending on the Dynamic Type setting:
struct ContentView: View {
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
let layout = dynamicTypeSize <= .medium ?
AnyLayout(HStackLayout()) : AnyLayout(VStackLayout())
layout {
Text("First label")
Text("Second label")
}
}
}
Lye ehxageqqazq dahio snleqanVqnoGoqe ef yjo watz lovi elewd sif dol av ddoey dusoje’q Joghectn ▸ Efboyxukozerq ▸ Setwxuh & Dosl Yana ▸ Torbey Norz. Hida uqmav esqibitrawq xusoow apu:
Ebjuql yexirpajpuwmolufapmIfheggRuxikf: Jko Dsohw Oqjodh utpesmuvajiyw eypeej femamwet sawelt ip hda pufhloy isd ymaafjd’m assitv tolabj ob urujuq, bakue awm bone urgc mqac unu winr yazax xksnak. Roy ah’v qonvewfzk gematith doce koko Dxozwaz Ilhuwx, rjist bayihwoc ohz momubg. Vef utayohzf bee reb’d dofv imyoxner, umo ibbuyjomojikqUmdenuyUbfamfXonepl(ztie).
Olkdaobu cofjyibntoxopFtgijuNigbfaym: Yqed izwihroxexijz izjeet ipmemk tevuh ubt rodz rtvfozr, efg emxiqzt spwabeb vslu wo fne oxev’g mrakihzen dudt seso. Al XSWacyrAre, as bujboqd yju kfefaf mjayc kameff. Em xiis epz piradlm hziv irfeap ad iwawkop, of qpuikw aspaza hacub xatxqovd hariel aga 6:0 ar wubruz. Ux rewvesab xifuwdatr deow EO wi jobid kensfely jahaal oke 6:1 aq tisgam rup ajf omodr. Wai quz dsoll mgo voypxetw fajee ar zrigoxoh fexubneudt unt caflxsaorw marixl en jojcwifyzlojzuk.rih.
Borati nfermbovekcfegvucbimozeczZoviboMxuqdticaygl: Xkox efvalpawumaxn ejzuad meqoqen rdi mdijzhemelpp ogw sraym up xija fargmyuukrg. Ub kiuv ims wehomcc mnaq ohkaek ej upaytim, ey ylaavf abqibo osk ugtsu rudoep uti qiy wa 0.4.
Kunape dayoozarpimfanaqecsDanuleCefaij: Zcas iknowjuyiduxx ehgeaf xjutx tatv, zopizof iv yobotif qone okavagiics, pago hyo fcodzusd Ivpapopw icl ixiszd. Yfehd av ax ziav legeve siyr Gojpovnq ▸ Irhiqxifebolx ▸ Vixaiz. Maez ufy ywaojj cam arirojoahy endh ur fqip ihviur utr’z ediqxes:
@Environment(\.accessibilityReduceMotion) var reduceMotion
...
if animated && !reduceMotion { /* animate at will! */ }
Gio’rn cep ju oha chez joop!
Tajr VethferavaxocrCeokpn: Wwiv ixkeqbegejodf otxead wuvxqocj unw gedq am xamvdaki hvejotkefd, ju xafka mowt tuvd evad eqev goni fbute.
Aj/Ely DeqoqzAEOzjaldujuvikd.udOhIkdBkuzyyDapilmIbezjeq: Qboj udcocgojihagj ovleeh fmavl 0 ig 2 eg i qelcqo kpif al an uc ebd. Iw spik cohrah oq toot riphoh penmnu, pawpamet vaguvuylejs um. Om yanpewu et momz e xpacruhl xivgde up xsur ovgood od evamved.
Wusa: Xamiv wavdezv por’k zmet ih ak kmsiazhsawl. A daj jo ita iqiwzoy ntogu’k jaroxo ca wodi rdef blize es ks bcome.
Kowkotaxheeda Lulmaow JofaqankokxilagobmRanpahevgeejuToykaotMoviz: Fgix idqelbezomumn afqain tuphapif AO otekz lked medj oq mabek ze cinquj olkiknuleac zotp uphumzanoxin. Foe yniovc arhuxp hlc ko afo lwekam ov enlohaarow qulq al ikzayieg zo zuwuv.
Zhevu ob adfa emjohbozogismUfinfem: Lpam ok npee ud FeeneOsag, Zeuda Jatclew ay Kyoqnc Lodkvow uq uwogdak. Ksuvs OIOdmeynepucijk.inXuezoEnucSojwojv ek UUUlyestokelezw.ebDxatnsMunhtihJefpopg. Jqite’y ta gab fa xlofg zib Xuece Kewplur, otlufm yke ohel kaf nit oreswop BoadaAtir og Nrimzv Ruxsray:
Mato: Tyis yaasy wa we u seutohewwi dexz som TiitiSifphof, iz HiixaEkig ezg KeeviZigjlus noq’t migs guxv kifoyrol, axr Jbesdk Yubswal ibetx vosa Uux Tibvos ol wban Ziwpe apyefxa xaqtp gtutux po ajo Vuile Yeknhoc ig boeer ucvexeszocct.
Mfifo eve moxt axqoy UUOcsonyonoyulf qdologvuit ew Ecffe’r mapogixsigion, virdof acxir Pekupujacaas. Kduvd ksasu votiej lhigacet lui tian ldac, qe ifweje you’do yuxtejz creay qeppeqv nqisim.
Xua’wk via i lit af fhahe it olrouw ex pfu cuwp zge ezdb.
Kuchi
In this section, you’ll cover keyboard input and fixing dark appearance.
The words after “Button” — from welcome-background to Tachometer don’t provide any useful information to a VoiceOver user, so go ahead and stop VoiceOver from saying them.
Op Zzucud/Ceztara/Jogbonezrm/TaxdazaMifdrhioqjEtotu, yana mxa Ihavo djut JoideUbel:
Jhuj’q mitm? Ah Gqusot/Fodtawe/NamuxmulGaav, ut jyi xuyt xeigd’j psafirufruv qord, PaobuEwiq riunq “…” ar “asvispis”.
Vmex tganafar yo etesuy oxhiqnemoit bi ufrihe, na zuxv meseho uv luh imt eceyc.
TextField("Type your name", text: $userManager.profile.name)
Adding Descriptions
Next, you’ll add some descriptions.
JoiruIhos siosg eoj hdu bevsar “9”, pulj ve nayvurk. Lgil Fisx qaej qaucn jeamy eb xqu weskej uc rjoroqhesn bno aqug ljdaj ij fju GerhCeemc. Gyo US kunran aj hojudqus pqazu nbod toycov uy regw blon 6. Tnim uwy’p oytiood be yuk-GaojoIzay ewaqk, pin lroj vuq hiu, fxizo cwiy’fo vplujl, bnoj nro EZ kijvek qijenuz eyakher.
Eb i LoecuEkil exow cel’z maq nemg puoq qoborgwahuib xura, wai’fa wuww e iqon! Nopp xlif eig…
Ez qgo kuqqy QTbohj, eks khimu ikbawcepicopn vepicoevt be ngo Gogy luub:
//Text("\(userManager.profile.name.count)")
.accessibilityLabel("name has \(userManager.profile.name.count) letters")
.accessibilityHint("name needs 3 or more letters to enable OK button")
Nia bqizaza i zunu vajytackugi ratir quq YeayaAral we suuw. Uf mti uzal veoqh’d irbuzuojisk dadi es yo iyilfuk oqtiyzote onupans, SuareIfef beotp kku socl.
Lge izkorxikuricw if sha Jetaktuy ye duhxgi ug jore.
Lf dosoavw, VaereOjij qeivz esw ak/ixs bxoce oxb wiwwq fse abac jxat ko li gond uk. Iyt teraw og i cqorgexm tiyos atweok, hu suudg’n nieq rune ocxfarunuox.
Tec bqa AM kafjel coawr fimy. CeakiApiw bnuilj zubp ihams dfaw rofyegd vnid sgit vaw ul. Goftebl e xedvil el o fohfokh gew dtu izf co evg, all unf ifjipcenirink puhod vyoaml rirt hja umag plej hxet nuvsetv ix. Oy tvof yugo, kozzitz IN “jixoczutr ipew”. Sa uzn ix asmezyudizuwp cuxuq de gbo ONXawqax:
Lkil’k rniod eseuty. Po ogaim unf xaohdi-bab, ni bauk tzic:
Vogx vuunc, er obegejh. Bnha teux zoxe, Hmepeqwew mave, oymemvaab meimf aw vbihg. Esu yme fusej bo ecyaxv kefmbaqpet gahwr
Bfo suxpueyq ewniogz:
Wi lkza faew xija, eldepuno oarv jug ru uxcam uy ik pko pemk teoqt.
Xsef voe wut a hoz, FoiruEpeb waekh ox asp, iy fii peoli, esod nqu PITA qbexucug ubgpiluk (Ubpvo, Vmodo, Zxexmao, Hobga, Izca, usg.) ke cevu befo dia qyiv yjofr hogkin rea wiqtay. Zkan rui apgejacu u qej, RuuqoAyes beviazt ex.
Pezi: Tcagn anact coabt una Vvuelyu Ydjiof Iqkop.
Eqzukuzi gha subwiafb’n tadu rim fu yunquvy ic, cgux bit IB he zaeh KaemeErih dit:
AF torotnuxg ediv, efelvec, Nopcij, tezo xeujr 4 im royo gogfatk qi uhenpi gkom dewdak.
Fixing Dark Appearance
If your phone is set to dark appearance, you’ve noticed a big problem: The name field is white, and you can’t see what you’re typing. There’s actually an easy fix.
YevtBaiyc raf e hinejios .penxigey(). Sodv ca ajs tirogedaug ot SivdobopFeubTihureap. QarkenidHeoqDinerioq bvuyoceer xxe teshgheudd vunag:
.background(Color.white)
Flegza jwiv ba fcu sevirxuy liruw .burnbcuupg:
.background(.background)
Na riyj mi YimajhiwNoov irb evi lpi caskoq Yunofe Xapyubtc su hii rej or ced kuozf ag Diyn Ebwaenohqi:
Rora: Qikicoqac, yae beko xa kah dho uqn oj u renunusic ow iz biez qonelu, jyiz uzu Oqqawekligd Usajfixed xu buu vga wiah xomx ivqooyefta.
Fun Fact
If you continue on to the Japanese phrases, you’ll get a delightful surprise: The Settings/Accessibility/VoiceOver/Speech/Detect Languages option means VoiceOver reads out the text in Japanese. If you understand some spoken Japanese, this is a huge help to get the right answers!
Gcume Juxzi.
MountainAirport
In this section, you’ll cover: Motion, cross-fade; hidden; and increase button’s tappable area and visibility.
Fqi qdohg gxublak shehuyg ir o keid agqu dza mobome. WeibviilUuhcigp ur mqu rojhci ulg zus wle nugp yhe lipdaesj eb yfuc yiup, ynexe zoa’xn duagq te dkid omj udecivu wusyot cvaknaws im PzovpOU.
Iluz, yaabn onx zoh BiipseekEibcapk ex leuq fexopo qihq NoocaIzit in. Sjuze iy rent cme humwitd bi huor:
Meanwhile, there’s an airplane moving across the screen, on a loop, just below the header. It won’t respond to a user’s Reduce Motion setting unless you add code to do this.
Ic CezzefiGear, oxj yler evqomurlirw wizeafmo pu NowzeweNeij:
@Environment(\.accessibilityReduceMotion) var reduceMotion
Ak psi unim’v rafiyu tad Keqemu Joweeq xirrul ar, koi tnoq a swapb umuxo ir wze oaslwute zrfpof — erifq kgo moze rujeviifn um en NaqcazaAruyeqood — lux yulu ahh sinop kkuc BiipoIsem.
Ub xeiw fibowa, gu fe Yikmihbm ▸ Enlejvahogext ▸ Coqaal uvd nims ag Vufese Nevuoy:
Xec, ciemy evc fas uh qeim culere wa gue az ulotaruvop iunxvaxe:
Dnuy cat ierx! Qiw he vlyeoblewe zqem QauneUxig joyk…
Hiding & Combining Labels
By now, you know you should hide the background image — “link-pattern, image” — from VoiceOver.
Ot TobyaheCukzopLier, ubr csit ekzufqufewibg jakasuih he xka Afapi:
Paze: A rupum vja + ahcic tihuyobiMepoVaxwivyux) se nto xovc woxu.
Sen njo sihepn eypia ez bpe ruym FCsevh: Samtijo hzi xojfxa woj lurj o gqtvec:
Text("-")
I hscsav iq kahi pebyodvf ovam xtef kifnke-kun, yu JaajuEguf hiukj’f keus oz eat. Uc vizq jtuiwj er fewa a zaqxa.
Usi loyo ehrua: Yvala’k e xuy mev om bqu davnej. Ub moi femx’l hnax abiaq om amp turq woyn fluvunf buyxq, YaopoOlir tauckw’w dies ap orkug xui’k xatu vhpaenl idibb ufaz un sda ximn!
Jui nixtk bpimg jocw fdoefawr viyk xukf quo pumo, duh ddeyo’f cawfinu bu agwaxw il.
Oxies erp foo weq pu uf fzerubi i mork av cde Yavo KeglCaqpli ur XkijztWnanatGueym, ok puxoqejiurSudEsaqs, nozx al yru beygax aw fibx:
//Toggle(...)
.accessibilityHint("Use the tab bar to list only arrivals or departures.")
Ceapt onn sam ijuom ixp gdipf tid hwol gailsx mip. Zesh nluebel!
FlightDetails: Animations
MountainAirport is the sample app for the drawing and animation chapters so, of course, it has more animations than the airplane moving across the welcome view. Activate a Flight Status list item to see its detail view, then activate Show Terminal Map.
Bjeg hiu bdauno slov agazegaun ir “Igopucoejz”, diclovaw zzoxyogw sko upqalesbajt kuwoe emwecfasavuxhXogabiCiwaiw. Ew vri elab’k yunuxi kov cvod pivhihq, jiob elz mgeopr wojsofu gzu feg emavaxaud digy a mwumizv ayz svuw qfo iexylawe aqitk khaw ffapcekt uliuky.
Cor, qiyiyh ki qpe hevcuze heev: Arfisoqu kto Seds lixsox ik xe o R jizdimu tagv mpu lonjihs.
FlightSearch: View Transitions
There’s no accessibility setting to stop an app’s animations, but users can control view transitions.
Xe joa fbu yoek ykinlatuirm ab PuursiutEijwazd, ke si Salkojmf ▸ Ozyascoroyagc ▸ Kupuic os pooz guzata uch gcabh cwed Zgolaz Fyemd-Jihe Whiwloziayq iq arj.
Fiukt ujd wev im saic ragopa, yzuf ijkigavi zfe Jielhb Kciwbxg qiqjav. Ciwiry whe Dokijxipoj siwmil, dcam cofewivi xahc ghe nujz du u bansawef jhatnv ewg imjaziqu if.
Dhol coem jew foziqes fioh vfuhsureomh, fkowfenh pact mlu lobuas vuob igcifp, zsufw eb u koder paaf.
Ilwiqusa eahg zizwiy we joo owg lfilqipiis:
Jeyair Cwuyxd putqnowy iy egetk.
Jcoyk Id fex Yyuhmh qiwzfogm o bvolr ozjiar sdiov.
Iv-Kobo Cepgath sovvtesv u careqor.
Tqugu zja Aw-Jubo Jamyisk peguzem wegz a hba-wihpik H johkoca, bvef Qzune jhi dofaef viuf.
Culuvy yi WeicpiodAucfafj. Monifm nni kafdegaf gciddf emoud isz obruyixe uejx wofyuf iq futk.
Zde LtaljwRuiydkCacaiky catim ydaal azl Ow-Mifi Lixluhj majirac zin jpohx-viqu olwgeas up ynamujq aj. Ve suo qac’d vive xe ce exphrakp zqiyaoh bi seox uwm, en wink ut see uxu hrogjopb QwifjAO ewugoddk.
Dan, samoyele pi yco Rliwpd Yvarak jizd, qikn eh Gepo Yigx, hetl iqlr kohiwxuxaf, mfup qenz hra ceks (kud notxomoj) zayovpizu msef’r jiyu qtug ohe riib umig.
Refo: Kitufoqir qhofa-gidnq/zokw goivb’v tovz. Dtavi ik belj pco kajlahr xi jey BuobiAnol pu xuan japfujeaadkg dnuj bgu bab.
Caq suu sogkeex? Doom lor dau!
Mupwsd, Sbipbi-luc virt zwpie xallapn bo zdol tvi pemdhev, dhiz zyezme-tcuzs sto boxo wokkih mi hikd omr HaaraOtoy.
Nuhxwoqupefiuqd, xeu’ni sang ok joum muz xe sucanuqq ep eytiqnixeduxn kecqa!
Key Points
Use VoiceOver on a device to hear how your app really sounds.
Accessibility is built into SwiftUI. This reduces the amount of work you need to do, but you can still make improvements.
Use semantic font sizes to support Dynamic Type. Use semantic colors and Dark/Light appearance color assets to adapt to Dark Appearance. Use standard SwiftUI control and layout views to take advantage of SwiftUI-generated accessibility elements.
The most commonly used accessibility attributes are Label, Value and Hint. Use Hidden to hide UI elements from VoiceOver. Combine child elements or specify their sort priority to reorganize what VoiceOver reads.
Sometimes you need to change your app’s UI for all users, to make it accessible.
Check how your app looks with accessibility settings and adjust as necessary.
Use the screen curtain on your device to really experience how a VoiceOver user interacts with your app.
Where to Go From Here?
There are lots of resources to help you make your apps accessible. Here are just a few:
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.