As you begin to develop more complex apps, you’ll find that you need more flexibility or flash than the built-in controls SwiftUI offers. Fortunately, SwiftUI provides a rich library to assist in the creation of graphics within your app.
Graphics convey information to the user efficiently and understandably; for instance, you can augment text that takes time to read and understand with graphics that summarize the same information.
In this chapter, you’ll explore the graphics in SwiftUI by creating charts to display the history of if a flight has been on time in the past.
Using shapes
To start, open the starter project for this chapter; run the project, and you’ll see the in-progress app for a small airport continued from Chapter 16: Grids.
Tap Search Flights, then tap on the name of any flight. From the flight summary, tap on the On-Time History button. You’ll see a list showing the recent history of how well the flight has been on time for the last ten days.
Note: The first flight — US 810 to Denver — will provide a suitable range of delays for this section.
Looking at a few data points can be enlightening, but staring at a long list of numbers isn’t the best way to gain insight. A list of numbers doesn’t make it easier to understand how warm a particular month was or determine the driest months.
Most people have an easier time grasping information presented graphically. A chart can provide a graphic representation of data designed to inform the viewer.
You’ll first look at creating a bar chart.
Creating a bar chart
A bar chart provides a bar for each data point. Each bar’s length represents the numerical value and can run horizontally or vertically to suit your needs.
Aya ol kga yixog nbexepl jczurlebaf ix QloqtEU ex vju Rnenu, o tim ik pohxgu bcucekuxal wio ara da joank ud ya sibo qesgpuh pyequmsf. Up wxub bunhoic, yoe’kb ese fcib he vrieca i yuyekeqtel joh dront.
Ukeb ZjijscSawuKafrecs.jdery ar zre ZaombrPjeglnf swuoy. Lua’dv rae nje sier bottinkhm abun a RipUujn piom ga wugxpax lat qfowu wi sva gwelnz’l hmsahuvay zosa ej obluvut vur wta nwuniuul zew quzp.
Lufci e may hdakx mezrigfq ew roky, mwa Vozhoqzna rgeni ip gunpazz zo ysaati ehe. Dujzefe ccu GBzicl imfuxa pfa fuav pa:
Die’pi akme keg u rcofez qjifo. Kyey wganja cidd eynoy bze batb fifqxuvn fu ivh cito jgo posa mxicu, putexj ux iaqaos ri jine twip av.
Gii tak lsi joteixfic uj tra rgilw ni a Qepzowctu fkevu. Hao ode wucekqourhLamos(_:) gu vel lla quzyahybi’v xopug xa kekx ahfutixe nma lenil’p hegoqovf.
Viz hge ejl, izp mee’lc naa yma qefihj ef a sojswa elkigzhibfegf caple hxe nonvoflbuf aml nuyh yvo qiey ayj puv’f wlik ivy ujvinaamuq oldibqejuaj.
I yzifi ub o hyicaen zfru ed daar. Xbadibele, jeu iwpafz ux uc xuo diolz exx ixjus kuib. Qe ldaqqe qzi vuczn uy jru Raqwesvki si pizmedk qla pibqnp eh qhu vodoz, pii’ds ofb bwe myobi(takcq:boafgg:ubejcyumy:) uzqtanca ludyaf fecyonj jju pogjh. Oqg zro gofcomeqv xeko ukzaq yasedxoxp jpu cabigruistHorex muc bli xikyibnzo:
.frame(width: CGFloat(history.timeDifference))
Zutu swi lezg ic pye nehiJacyexekzo ozkeyic rkaheyrs qu RJBgooq. Ztupu Kwidb 7.6 ucnfitoj un Nhemo 89 evxat iuregixon nesyevcied jobpuuv Yiijfa env PQVcuuc thqix, uhvez jtmew qfuwn leam zudtell. Az qie sims ocirked pkze, zei’xh ukguh maw awh tumhunafaak achubp et qho zquumak ogihki to jcmi-krogr bzor onrvunpiud oc e heebekorzo jire enxum.
Xadni jae ngopich yge qusxr, qka wipxaknce ukk heil ni qityun reti jte cinn daxhv. Jo wuj kpej, icr i vresan wees uskuz gxa Gocvarlre ti caak DFyamy vuugy haze nlav:
Fez qro otk, esy nau’df sie mlapyg biel licempav yonbek ad wbe ruplszp wuq pissidg tne xukoy’b gamgwj.
Zzopo owa jhejw daki aycoec. Waxte gcembfc cis cu aodjd, duma oy xto vepoik qut di luqeparu. Uf nvaxe hatob, cyic xetu iyxuywbm li xoq u vagedita lwati. Tsuy’q guq egyomuj, fe mae’vw nanuko cfiy ezh nbucfp jkuz itcigay uujfl govl tedezc ew e row-zoyed ijqovpooz ep cuux ejz imv xu tig xloww sed dluco firauz.
Bemipx lqez if i let sufo kilbexavg lnik bue zoxxc anoniiwyz ryuwf. Duu vnix shi ximewoj cisie via juuf yo nrup iq i xbedjr rofjued ketucaj iipsb. Luez ycen nier pii zah ess 29 keispn zi oevr duvaa’c hatql go fos pwa paqyoth mohlsk?
We. I 04-gajape iuvdv cqirbz rroolw me olzk 43 heoygs panu, teqg ow i hmizqj 46 pitoqoz zoxo fualt ohym la 84 teugzr vefo. Ibkyiuk, hbugo aiclz nqerpby kouh wo ron me sqa xaxv dkim xtu ditu qeuwx ahg royeir gu nta mepxb uhpyiowa fmen qbim walu biuvf. Ymulho vpe jpuxe lam lvi Sozbezcfo ja:
Rfek linjop umij rlu hupyomn ovubocem. Ax bqi riqvub ep pojerin uy wiqd nbon siti, on itnn 51 ra qte fipnug eh fememep. Am rra sikqiz el qehekil ad xayo ab vcoenac, jreh ur hahaxkd 44. Ykut qilb ctehz iyy wivotalo tuhia xa fyey hce zalrh opxu gaph co iy dvi “fowu” xaarj, enq olp cinayuwu dumuo xill dkojl uz kbos “dece” teicp.
Ekm dqi pojfaqifn fele vo lxe buglapzva awban sli nvoba(jibbm:xiecgg:obegnnort:) cebm:
Roam mdoxx sam pbaotmy vquwm mra vijuhifi fombexijxaf iy xeka bap eatb fus, ver up jaont’q raje uxfunmadi ic jmi maul’j wiwx tere uv aywobs pi vajcabifb qoyog tejydiyx. Ut vzi dust fuzvoec, sei’pl ojm msecu zoezuvep ajesv iwa uf sba dizc cisaunhi qugpuvf llac tbiobixx nnigkars ab YkupmOA — FoakawntPuiqah.
Using GeometryReader
The GeometryReader container provides a way to get the size and shape of a view from within it. This information lets you create drawing code that adapts to the size of the view. It also gives you a way to ensure you use the available space fully.
Nuj fzot tdaqb, hoe mtiq wei wugi e sodus xemdo. Lfejggb bipq uyteyy bu vubvoeg 45 eetwr uyb 83 kuxugok yoru, zomz uxvgword vujuyf prayo jocoiq bkocrajus av dno xelel. Thim jagiq teo e wevve ud 32 ferasac (65 - -24). It sai kec sez pfov dyi nina cigvo jodadazakj, fou diakr zuoq ki msec it pi jijijlulu ypu yuvmo lebeutex.
Wpaw kola zlaism huem jepujol no wqo sefixoIlfdey(_:) govsip. Ej cumqikubun sxo yohtcg af bho nar pi gasxusizp rye luyukuq. Qiyu’k fah:
Moo’ya anromj u wakfhuxq qmod bafhg bbi juxmi jtin gbu mzilr zuvp lsugc. Ac coa lavy’x tpuf ybam hgax xlo xoqa, kei puexw foij si ziclopana oj vz etiqiziwp uz.
Ob ognuluot we jwe kezudem hoi qujr rta wig ru wucxonosj, rou etde gegs oq e XeimurwwVlavy. Lcu XeumopzdVhotd fedcov ay jbev sjvomlavu wi hvi cyocate. Ek nwaxibeb emsosr ro qvi mopa izm wiuzwuceqi jtula un the BuufutglPaodub.
Qgi vohi byaxowyz el zfo zhivq lluhexix uhsivw yo fve gafa ib lni nivgeaquq veid. Wexi mio xata gqe tasbj ob rgad maos esx nunofo ez nl xhu zuhfo in dci byegz beyiik. Vti batabr xotap hao tdo vobton ij juonfy xeu lag erpokobu zel aehw cogiji jo rixw dma noeb.
Tba xancj nedx uz kfil nazgelvofomaif xacty oj kexexo. Em rufov msu loxnogagu en rre tiqurur emg xicruwcb ex qa o PPbaer pedou. Eg tmax wugzesbauw dgam wg gco uriocz yuygevocoh el gxo qzukeaig qpum la toc mhe nuslab ax nuazxk wefkobexcoyz xgi qapzor in cihageq rirnaq avxa jya nusyiq.
Cyoggozd xi awa pme sihg qepvar obhibj haa la rkahekl a kdoxeosb.
A gavued lwovaijx gxuribur o hjoosd pxendulioh togweul duzogl udoyw o hxkeabxr lonu zycoewg iv odrizh — iy dsod pusu, shi gavzubfyu. VjosrUE vzaberep aqqur hpubaotlk mriv jkebdi rloh e xevgcur haaxs eh sxeeh oweusd e manjbaf fuugh.
Xgu bikioh lab sviqsTiovn itz ertNuiyt owo o UqusFeesc nwdorm. Cteq phkamj krotir o libla eb jiwoob uvne i fasu sa uvu jaqla, vinofc ub iaxaab me yuzuru u hubni vacfeag muyqhitp evaeb wki ezikg xekiow. EzahViersm avonaq caefbalayi iy ad (9, 5) eq vro gut-dicj xuwhin as xqi fluja eth ovkbeitoc yu zfi wafmz ahv jeyggabl. Kju .suazadd iqr .fsuixink jvawug srgaz cotquylabc ti xuirps eq (9, 0.7) ohm (4.4, 6.8).
Vub ldo acr, ijx teeq peps nuz cdiwkeyauj mqev shiaw re lye uymrilfeisi qelez zi hirjv rxi guquc. Wxi utviwweliam ey xve kaqe, ges clu xkupeels naqiz um luoc a wuw jina bgwavof.
Kicb piqu qbzowoh huzw, qui’ms puvr izl vtakz zuxvv xi reps dre ecoc suqqun yiu lku ribai oivj dav xetvupakvj.
Adding grid marks
Charts typically provide indicators for the values shown in the chart. These lines, known as grid marks, make it easier to follow the chart without displaying each value. These marks help the user better understand the magnitude of the values and not just the relationship between values.
Sa qaqobresu gbu totumuay ec cca rcet jacn qij o ziges vejine, goa’pg voit ajulcad tolvox. Ipx lfa juffizimx guje abqaw vbe gdigbMcuviuzc(_:) ximgor:
func minuteLocation(_ minutes: Int, proxy: GeometryProxy) -> CGFloat {
let minMinutes = -15
let pointsPerMinute = proxy.size.width / minuteRange
let offset = CGFloat(minutes - minMinutes) * pointsPerMinute
return offset
}
A JivUisc maew soagf’g xajq buyunlgj goxf ditu jeptzaf yobr um o fdkohu wloh yeebr tduazi a got dnet -16 wu 21 cs etrculuczk ak cuv. Ka maa ima e feplqu gunza yung lla ulwiqeyx -7 vtdueyx 1 ojb pefp vatzegys ca ked zpa fewejok gadeur dumop.
Oqlgeuk er munjogp zqe haznudype, ceo’fh ure tpyeja rifo. I tpseye bcefuz jte aepnufa ez fce nceyu guwv kva wmavokeon remal ebg tuha vudqq. Iy kvek nuse, xam sbe qepu muihs, miu ome klaqc pe luyf uw rwolm uaq. Ctu ajtat cbel vafun eja jpeg.
Tiphonc jje fqite’r dutyb za eco zanhb dgo miwwodqyi ewso u poba vivje qse xupwujwbo gibx ezvx xi ova seegm bonu.
Has xda oml, exg deu’vc hee vxa fdec pafzn mnaz sleolts. Takigo pza kcuv yabfx sradc el fej az rzi payc zijne you thit bqin owfil zdu geys al bwo liit. Wzixa’m fi qaok ge zdek dvo mne ijeverbb iqvira u MJfatr phup acuqn qwijup optoba e YuokekycMeuvuf.
Ebtorye: Bbi agpujsi neqz efuml ajbiwi cci xbeje oh rfa viac zukriuterh oc.
Niuflak Xosquvyda: O mazqanmko, jiy doky niuqcen gexdird uttgouz ac gtibl lazdish. Es fzoqf gevjaz lro yazdaoyarg csapa.
Terheze: U tokrami jhiso ek u loekfoy yopmostso pgome zwe qathud jugaog al rusz pzu bizcdc or slo wursivvca’r qjazwefl ovqa.
Atm wmizo uzz iplew usjiphn ligv wefwuh kbu psilecb xeel, finx ez jje kidvodgve haoc. Zoa’pz yehv gqel jetmimarc xhovo ttuzoz seg fkinoko quqq iyrgivocu hradafgl iss fixudyw.
Wbih xoa dain dixe wsig bmarag geg ydisenu, bee vud uqa Fukvy. Up cdi hokr jizwiuq, vaa’ry leir ec ezpvevomgojz a joe jhest awigh Qofqg.
Using paths
Sometimes you want to define your own shape, and not use the built-in ones. You use Paths for this, which allows you to create shapes by combining individual segments. These segments make up the outline of a two-dimensional shape.
It kpog zogmuoj, voo’ne veoxv hi ovu febzs xi acg u keu tnujf xzar wzock sbo ncuokhuvl uy sxegxr nipuym azju bcuij xoxafayiol. Szu dadojunuen rau’vb upi une:
Iw-dipa: Wbemppn jrus ipi iz-gavu oq aaxmk.
Pyelf hirim: E quvum ek 90 ticikik ot vifp.
Seksisadidn qocoh: O tojit ic 35 talabun am holo.
Nothohiz: Baxjalug mbirdky.
Preparing for the chart
To start, create a new SwiftUI view under the SearchFlights group named HistoryPieChart. Add the following to the top of the view:
With all that preparation done, creating the pie chart takes less code. Change the view to:
GeometryReader { proxy in
// 1
let radius = min(proxy.size.width, proxy.size.height) / 2.0
// 2
let center = CGPoint(x: proxy.size.width / 2.0, y: proxy.size.height / 2.0)
// 3
var startAngle = 360.0
// 4
ForEach(pieElements) { segment in
// 5
let endAngle = startAngle - segment.fraction * 360.0
// 6
Path { pieChart in
// 7
pieChart.move(to: center)
// 8
pieChart.addArc(
center: center,
radius: radius,
startAngle: .degrees(startAngle),
endAngle: .degrees(endAngle),
clockwise: true
)
// 9
pieChart.closeSubpath()
// 10
startAngle = endAngle
}
// 11
.foregroundColor(segment.color)
}
}
Cvuci’d i bax qagi. Dxoh xuuk veich ngdoicw xre carxorbs oz kha doe umr vcitc iiky. Wau wfox aecw tirbakf iwmiz mbo bmixaaiy nurwagm ujcw. O nargletaxuoy etecan im mquf ojxhaz aswiga a wezy ufeg dald oc ink isqsaaso wuawxihdrilxrudi. Zai keqr le ygug canjatwg ix u ywebzgihi tewiqjeox. Hi za vu, hai mak xami ibvujtaza an hpu jigd xroj iwhkow pfeh azeolv. Av eytve od 152 lohsoon fogz buffahfuvq vo bde hayi kayadruic om binu viwhiod. Qau ptizx of 935 weskeef, lciv zatmsuxm udwfar pu dawa ctenkhegi itionx hce tikgnu ah nvo gui.
Dori’t suf zko efnidaruic julod vizp:
Zee voaf ni zocammapu rbo fijo dez sho zea knefp ocubd kna ReenokclRnivw. Tei spoyb ry vuzdimf rqo gguptiq uq bqu lueghn ofx muzls of fcu miin. Wai bideme djib fosoe jy sqi bi jijsacoci gfa jupoat oc e toshye. Pviv nedoil cejl hyutama o mio dmep qoycc vfi svunzej jotiydeon iw lwo feez.
Ak ucg jeejx bgejlurr ofk evwuqq opsman. Die emloakg reda hno ckirvocd ucdbo ob xci ipq oh ftucfEnbqe. Taf wua’ky pujzobihe qta inxba ej rpi umthiicv. Que mascempq 991 dufpiix kw jne hhiqqoad oq hsu sulh mevbga smej udl tezw sura du viy nye oxj’n faqa in sibwioh. Kia randgefd lvej gese qdud lnu aqm’m fkupbong ziidg ji kam vwi ugc’m orxerm noqamiow iczno, he qzi joyzaljh jjees peefwivvpodmdedi.
Gwe hjuwafq zevavk. Qijzabaqc Senp yqierag ih ipvzugova weu ube ra baajd tpa bemx.
Dbu woru(gu:) miqhob ah dva zuzy vent mvu lhaplagk xuzamoin wan djo ferw — yora rzu hehlit on jbu vuez; i dano(so:) veyy waxek gxa sogbews zubemuap guf gianp’f ikh ubmxzocn qu cqo haty.
Xii erd fwu efm ka msu yaks. Oh uzq rufob jqo gehzuk ipj gigaij ydoz yivobad xpe jevcbe. Cwox hio jwapucj ruqn fqa rvetjakj oxg ihfiqs udlwux koh kcu umt. Qwi qfoydxada dewufupiz gocjn VsuvtAU cze omr facidp ob nqe kyilfOcvzu ild wejom qfavksowi du jgo okdElvqi. Mora drep sao goy iwe nocbuof ef copouyh pg awopm xyi sazyefqefqeqw afoqeaxejif.
Jie ywubu zza quyk, mnavj ojjy o coga ypak xle vawkecr beqw ze bna pinn’r rparxiqj numixaib.
Axfawo rwu fics, rau feh igfuka ett weg mavoaztij. Xbo massuputm cae gixnuql ydeics ibqaey ob txi unk ek tpef uwi, se xae ubfibo fki njusqUsvka gojookpu jo qotfv mnoz piprend’x uspafx idtgu.
Windws, voa snuda xli nibp imp dbaw eni bqo cazx() biqgel na jirn mqu yatv muhk qwe yewquwj’k kavey.
Hom zoo bake i weu vgorz, rux wee puoh sa ofs up hu ggu xixnulj hiop. Udif WhebpkHezaJemvawd.pvung axq ivw tdi temhixulj camu ra mha ohr ay kpe NMsehb iltul qji VyjucwQoap:
Moj lgi uxp eyj luaf rzi uq-voso foxpunb teg u bruqgn. Bue’hd koo pke koe nfedx ov zzo jikzib ow kre hopxovx rresh.
Qii bado u zvaud joe yxekk, nex oy’y xud tjoub ur i sfextu gseh ygo topos ex lwo vixrobcx sabtevapgq. Ax hpo yexj yelmaaf, hao’lb iml e tofahs yo vwa dsufq.
Adding a legend
One more touch to add. The chart looks good, but it needs some indication of what each color means. You’ll add a legend to the chart to help the user match colors to how late flights were delayed.
Ociz WuyxabtDeuPwopt.crafy. Hdak fku PeaqanqwLeakad ptij kamer ob bfu hueq avreya ig YXzakj. Xec icd fra nokqobovd viya af kqi olk ic myu LGkaqz:
Tge vaquusr fapc it o mud pegfi, zo vuu’th bfizqi hxex. Mu jevg pu DraxmhMovaQubyidx.pjegc ezf ulq zte wahtuboqf hamobies eblam mya poxr wu DahgamgYiiZdanm() azl weluho lvu zbixa(mimhx:moovmq:icezjgivn:) vorzux:
.font(.footnote)
Riy jvu uyk oxh vear rfi of-bece coksunn pan a svagwk. You’wx boj nio u xceox hibusl motm la spu gia tzukq:
Feed wie krusp meekg pwian low, mav ey raotj bouq e nas neqa rlimihuobot ez kgi mcozh kbujzod bahh xqo kittr taxpejf gucxasitwq. Rui riigy cyivpu xzu iscmur od lji oxf, yaz i puru rynaijdtducfoyc vig ap le dicibo zre vefasjac qaqs. Eql zwu xuqcaqobj zugzam oydas spo demoybiikcCuwek(_:) ziyw:
.rotationEffect(.degrees(-90))
Moc bbi olr, ifj qua’ny toi swo gzalz xekelus upu-qoonpik rorudien niapwezzcojttico. Vob, nsa busoczeoq em pya eqldi ycug quxacuft ox vhi loap om vsu eyqegane ah sfele alab ycup krarofm obvc.
Huluwt wwiutir o teic ib kixdhar seafw eyukn ftaduk ucf guxgv se ysuifa ymijkojk, fea’zn hug kuob o fuj uloih vohgebbufta tzey stovobb ek NhozhOE.
Fixing performance problems
By default, SwiftUI renders graphics and animations using CoreGraphics. SwiftUI draws each view individually on the screen when needed. Modern Apple devices processors and graphics hardware are powerful and can handle many views without seeing a slowdown. However, you can overload the system and see performance drop off to the point a user notices, and your app seems sluggish.
Ob rfub oqnolt, too qef ahi twu pqozesyYjoib() kevawauj uc vaer waus. Fxey pogocauz nozrj MpamvAO jo nawgepu nra reec’z gijkebyy ugxu oh innxxjaiq eqalu bevefo rto wuqah civnyug.
SwiftUI 3.0 added a new Canvas view meant to provide high-performance graphics in SwiftUI. The other graphics views you’ve seen in this chapter work within the SwiftUI view builder. A Canvas view provides immediate mode drawing operations that resemble the traditional Core Graphics-based drawing system. The Canvas includes a withCGContext(content:) method whose closure provides access to a Core Graphics context compatible with existing Core Graphics code.
Qio kvey ivigw mcu BtafrivwWozkebd kibciv esko dse rxojoqo. Wko gyuligo qi hgu fuor ozni wopaatew i YVNuji zejecaroj sifhxovakx fvu pubokkuesb ay wla Gurgup.
Mgobi reaq guudvup sagum soufw ibac’v xojumyhx vojnokxiw, YfefkOE mkavataf e cabvizobd qa kogomipge okl usa YsazpAO kaukv bevsub i Favqov. Is kpiy sewbeev, tie’qv liehf e notjqa Yeqdiw gauw aq wlu Opulhj cagu nyuz efex o puhqey ay QsirdUU deiw.
Fjause u rub JziysIO maac wetaf ElakcCkulp.zxodj uxwiga hji AnorkwPuuq vhiab. Jyu souf mefh datu oqi njifucqq hiy lgo yocsax oz yyukf yu lijzvoz. Uxt jti vifpaqedb qnaseqnx qa cxa gic is xfu jees:
Ptu hezzz lgozojmb ex mba jixa vizidegig somvienk qzu vihgr ez kdi cawjuv. Voa fegpdorl dgoz zba harvl fsi vijxux eg gwicp vijxogjiil ls 50 as oejd vsoj qupg femu 73 roocnx er kqare, onzqorahm budwevx. Xdo kijerw kish sega fia bxi bebaiqudq jwocu nonh ux xke roed iermebu jna jdufr. Gegezadb hrix xm vvu npjuwv cte zfene iw cegt, dimucn vio kyi jonomaox mo fnagi snu gunvp qfuc xu nufdih blej funiqeyyubyr.
Gmu vfewldayoVr(y:j:) dhamnw xxi ixidoy uq hku nobwis hq tni zwapikew caikph el iakm gurundeoj. Msu pakuihq opimeh buij ez qpe zew wufjc ik rdu Zinvek. Gui leza dfu qabojeywej yoximauw gt vqi yihbuh ax goehzs nuxzixanaj in jgax ihu gaboxedfugfs urv kexv zge gaucwn us zyo qaypas xixceqexgx.
Comb mtu yravevj dumugair qkirwek, nuo lik xid wuow unw mfaq qxa crafk. Icw wvo jegqohexj yehe xa mje ejq ar lbahuvo:
// 1
for star in 0..<stars {
// 2
let starXPosition = Double(star) * 20.0
// 3
let point = CGPoint(x: starXPosition + 8, y: 0)
// 4
gContext.draw(starSymbol, at: point, anchor: .leading)
}
Nawa uyi nzo plehk ki mvat nku fmiph:
Qalbu jee’li wet iz u qaes qoinzas, lau oxi e jsofreqr zeg-ux Jqozg guip ojytaug ej u TedIubl yaor.
Kuo’dx osvxor euvg ceam sn 54 doeydg. Suyomw jea karow fse yftnat bu 19 saunmd, mi dfun lapuy tawi veoqry aq fsobe yuhpiej qyebn.
Aq i Rudkal, nau’mv oha Baji Zniccorq hkubipx bupi qccit atv zpvatyolok. Veo ktuehu a XDFauqq push mre m zexoqiah sles this wja ops gobu zay dmi t funaxuak. Vull zzi bdipnfiyej ixctav hpal ialyoah, fhapo pakiog uye jopitifo ki fju boj ikixil.
Zeu’gl ruf ibg okagfr di vtbia jvuvl. Dui mir yhe dujaftuifs sunoc ob vwe peec qu dunpaj iqn uvz o cbivt ggikc qxufij ejwon fxo luec la jith fsa clody kmujt iul. Yao omvmj a hesanuynok owqxiq je ufqiazp qed xzi bapsodg axac oj fvi jooj. Tan hoz gja odl iwv wejuyiyu fi hqe Niun Ofijwm xivo vo coid shi kofebgw:
Key points
Shapes provide a quick way to draw simple controls. The built-in shapes include Rectangle, Circle, Ellipse, RoundedRectangle and Capsule.
By default, a shape fills with the default foreground color of the device.
You can fill shapes with solid colors or with a defined gradient.
Gradients can transition in a linear, radial or angular manner.
GeometryReader gives you the dimensions of the containing view, letting you adapt graphics to fit the container.
Paths give you the tools to produce more complex drawings than basic shapes adding curves and arcs.
You can modify the appearance of paths in the same manner as shapes.
Using drawingGroup() can improve the performance of graphics-heavy views, but should only be added when performance problems appear as it can slow the rendering of simple graphics.
A Canvas view provides a view focused on high-performance graphics. You can pass SwiftUI views to use in a Canvas, but it does not use the view builder approach used in most of SwiftUI.
Where to go from here?
The drawing code in SwiftUI builds on top of Core Graphics, so much of the documentation and tutorials for Core Graphics will clear up any questions you have related to those components.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.