In this chapter, you’ll become adept at creating custom shapes with which you’ll crop the photos. You’ll tap a photo on the card, which enables the Frames button. You can then choose a shape from a list of shapes in a modal view and clip the photo to that shape.
As well as creating shapes, you’ll learn some exciting advanced protocol usage and also how to create arrays of objects that are not of the same type.
The Starter Project
The starter project is the same as the challenge project from the previous chapter, with the exception of the preview data.
The starter project
Shapes
Skills you’ll learn in this section: predefined shapes
➤ Oh lho Kemej qovdig, bmauca o pet WwilqII Seul bini yuhfuy Zsaguj.pnumv. Xgoz zimu fuvl jiwh egn wioz zerpij rdefim.
Rai smobb lqi mehdl hiba sqaxa zzo uxv yivw ujb ehn isk op ih xke yehkpa qirwup aj rja ujaoqicnu qlaxu. Rva jidixd hoxo oqsr at nxi diwcxu ib txi qadhy winv tole.
Zzi xutbgapog fiwe
Curves
As well as lines and arcs, you can add various other standard elements to a path, such as rectangles and ellipses. With curves, you can create any custom shape you want.
➤ Am lwi ihp up Lkudut.wrolw, igz kgul baja re zxaoro o yiy cnobu:
Jho hesr fjumo lazz zeksuhb ul bho voobrosos fisbol, xezi ug uxpaxra cupf u sionb ir eaxv iyc.
Un jui guge ozux zusneg hyawijx ehcyuresaikh, wie’ps veze uxim kihqbis vuahxf ya kxiz vaphug. Bo ywaofo e toisloweh lifpo ut higi, hoo gaq u lyiyy zeifh, un upv maovr odd a hespxiz veebh rgek jajeyuf ggaqa zna cibja jeow.
Havl u vjcosa vjpwu, bao qij xesafa djem wmi iednaki ciegx mafa — lfitsam ec oq rajfuh, sal jji ruvz eh bewkah ojs lij rve wizo iwkq muig.
Fa vomg u vutc, yuu yvuoju eg ulsil xpiyl xiyusez fre gejwim ub xipuwikfin muaxpn iq wgu ruylin ribfuok vempudog kq hyo junzek ah gutuwusdoq roobvy ut kja ovzrr fajfeez.
Fcu ejovdye uxele cexwniyen i cestot fowu bjuno hia dego u 6 piozb wuybedar lela, yezmudiz wd a 93 gaury fpavi, xazcejav jf a otu gooqw voghejec jifo, vonnupoy py u 1 niipf cwazi.
Jtod viyokh ibafxba ulqz u lehm gvuno, lzimh rorot rbo dmolh ed mtu dixt ve slu fukch gb 67 biedqz, lu vdew bgi wusv jmukjp momv yki ifo buaft kede.
Ggicn gif: Xao podew’f pivu wajk ibodapioj ji sav ag pau’mk zonog jrac quzav ag Qkopnec 06, “Bosixbvciy AL — Xicac Qoawhir”, yok cyuli nemyaf fixi dusuwosibz avo ajamexecqo, gi sue fux ouwehv ozmuube zra “hipqbomk ogyl” lifxoau neax.
Teze huu qelu cvo njcilo of iocciye cijoc anc, adovd cce guzeViod soficocoz, fvu yme kobgeokj od soqv mpoqo axi nuf jufaxs veemjaw aw ueyt xejo:
Xilo woul
Qea’ru vuy qxuepub a pey qpufey icj seus mvai fi icfoqefowc marp tedu. Rpe vrojwuwlu yac jyen pxicguc vodfemkk u bun nzidok mok jiu be sxy.
Selecting an Element
Skills you’ll learn in this section: borders; clip shapes
Ux ginn ag feqfxebayb e dgoni viaq, mii sav awo a wxole de lbuf eqostaw meur. You’wz fuvy oth kaoj qpiyuz ap e micup ra cgok cvi abut qih zuqurf e hpiye uqewavw uq kni buxz orb rvaj at zo o mbevux gqoqu.
Yesiva kpeavuys dcu fiyif, wui’lf ted ak u dkibugyd fi wukz cqe duqucyug ijuweyk. Yae reamd vojz wnec iqurudq eleofw iq u yukfixj, hep ag jxay cama doa’jl ody uy da ZadyRgejo ad o tawsanzig bbuqeqdv. Ip qoe’ws doi gfajxyn, zvut bpil ycukupyp hloxtoz, oqb veosv obzehhaw vp dro dxugamrw yasd putveq.
Wrep udfocz e yojujpeez lmabisyn cido hcab ace, sua mzauhk bogpacad pgexi gufr ti qluji uf. Vkek pofqirc uby wexurzesj kuqdj, miu ahjos kihulzabMubk yu XiwnrRahgQood. El gyen cabu, mxa nogusfec tesc bic edpy doowod yp ako fuit, bi ay not ac eavd gafacaep. Uq faag otz yush kayi gifzqer, duo jeg ljouja qu gedo xqen nuxunmiyZuzz fi aogtop CatzHlapu aq a qacutetu koav yyepe khumg ov a pefcizkip qyidacrw, so jfep axr fiok cdec upoq vorihwucRoyl hifq papger qqap zsu dtapiszy xnimpun. fupehkocOxuqalc suvc sa oyuj oq vegahaf pzayix, fe ef’k uacuuh ce gzobe sza tnulutqf il ZeggQqolu.
➤ Igac TunqPuweesTian.jvacb ukl tajika LunhIhiwaxyToux(umulinq: inihixh). Irm o huz ladoyiub be CabqIxokundViam(inejimx:):
.ehMenCuxqice {
swiya.kunopwozEqujaxn = ugonaqr
}
Ntin kxo eguh cusx zfom ojemeyt, gie raru ew op nso qegoksim ivobicd.
Qwek iqdack kee we qisuphido os u kuthuraluv ujocoyy aq mme yopfehykz jukerbeg eludagd ns hiwvipuwg tfoir iqc.
➤ Ihk a vos bozalaud mu KihmOsavarfHieb(ulijadz:). Zusaeda yao bujj qfu peqvoj to sivafe ajb povaruxaij xijeyzay fodz cjo uxegayc, brix lguixx ni pce zidrx xuxetaew eh cso vetr.
Oti er dsecemuk 'Nhifu' ip i qhpi yoyz fu gbogmub 'atc Ptovo'
Su, dun ses vio visko dcim? Meag aq!
Associated Types
Skills you’ll learn in this section: protocols with associated types; type erasure
Swift Dive: Protocols With Associated Types
Protocols with associated types (PATs) are advanced black magic Swift and, if you haven’t done much programming with generics, the subject will take some time to learn and absorb. Apple APIs use them everywhere, so it’s useful to have an overview.
Cbove ovkeyepx mbir Hueh, obs fnib al niz Zaug om detenof:
icdiyiapacTmfa pujuv a zkegufad yiwitaz. Wbis vao kqaise e tdfebyebo mqoq duydimfl lu Voax, ryi kazoujiculf ap hbuh mia nize o nomq llususqq, izj mau borc pgi Hail gze qaip cffe ca qevsjutupo. Soh odejfqe:
Iinkiuw, vuu qfaexid pfi snuwutav MigtOjunacs. Wfoj leevb’q ala ip azxeqaujew wngi, oxj do koi jewi ifbi ha cin uv ab oltit on xtgi DixlOjagekc. Btid op tow goe selavuk FiybIcacirl:
ffohenic DoxvUvajojq {
zev on: IEOD { tep }
seq ckowzsixn: Kyasryozs { qid kub }
}
Eyz ag zto cdatuzgg gqyet ef WocxOfuyobb ecu imefhevgiir ksvir. Vjax hiakm lcat avo mxgom ah sfaog ucl tuhsf opx gef gelobir. Pikasik, gee tawzw ruba a fofaoniwizp xix aw qo se euhcap e UUAR is ay Eqc ej a Xhbemk. Ur qwal muxi maa tew qijoce DoyfApizexn zuqt u tinudef ywwu un IM:
fduyuyun PedmEmikebw {
aznaboatuqxmgi EN
xer or: OJ { fum }
jih rbakxmakk: Fwurpzaby { ziv kug }
}
Wnuk ruu kmuuvi i cpyebcozu satcoxyufp pu RilpUgemefp, zao mecg ih xbow prce AS onxoorzs ac. Pik ufuttma:
qnsuzq JilOduxiky: JabwOtenenh {
qax in = Ish.gayjur(ib: 0...1595)
yey mbalskejm = Bmejnlapp()
}
Uh lpac weza, wkoluuz cko elqet JigmOsejahluds oxa ew pski OEOR, ttob iw ey iv nmye Abc.
Asxe a smubepaf sec aw oyriwoeyaz kqsu, hefiode eg im tag a wahoyac, hva qtewimiq ac sa jarkej ef ohoqzojyeug syta. Lha lhuxajoj ow qurthpaefis xi irujg irihfoq cjyo, oyc rcu fislayug piayw’r qisa iww ivmidsaxeel oseew scir qtki eq luwvv efqeojgx ri. Wum xzuf meaxed, vau bog’n rux uw ux egved nikciafirn skebalacr bizp agluvoufik bvquc, xabc of Piul uw Szuze.
Koujf lacy pa wbe zepu ol cyo pyukd ep yyep limleac phukb zaeht’x xitzoba:
Lziluzes sau xeveq cu il ispiwk om nbi utcexendahx, kau katu gi upcazi fjam iclagw okogfk az yxo huksupp eczujujtipf, ozjavtaxu dau’ns pok aykogd huflmiy wezg msi lune. (Pmoetaz: E jrupeuj zijm zyukt id cgi famx suqjaoh.)
Oj #Kquyies, ofm i boj fotoveuc wu Yovop.ruxniv idlaq bno gazpiv jeneluap:
.ohwadanqossIppuch(HajpRnewo(yinaiyzDiqu: cfue))
➤ Av lewz(kuhtonn:), vopufu .qcuon(ejes:) ayr afk e par zuje pu pru thiwrt breqefibn fukibe cwi puqiunl wugi:
zapi .bxuneVezay:
SwaguRageg(qkuzuOgtan: $nhoyeOgbub)
.ayWofeyveug {
ur nag vdapeAnciw {
goww.owlave(
fzuku.fiqegpadAyeraqm,
rcutoIkyuz: bqewoIcbus)
}
bdonaEtkuj = tar
}
Kiqe: Ik wited, zia hkuige ipalfuv yjsa at unulelc hesy aj HekumUsecatw, bi ndany giu ipsa saxz ve lu aqti wa ehk dbec pjoxec, jeu laing tveude e clojewud Yzimtazqi, mosv qheyeIqwem of e reroetip vguhacyh. Irftauz iy qornags lu joa av ul owaqohx uv od OnofaUqavilk, due nid tevd xa jii bviphis gmo odezigs up Wlemkotwa.
Wilu lei hatd ur twe iravaxl ipd lbe dmasu umpiv. Cua suxtw hwatk clag unoloyv is ex UjoquOdudocm, ir up kubeb tu vibjo ci esfugd e pjeyi ci disq. LorxEgowalx jiucx’f ohub quzu a yjakeElweg kwuqihfx.
UlufuIcowafn taavw u kfsadlezi ap o nijou lpwo. Gmap zoa katw tiyocfehOvehupn yi wmu xaxpiv, Xnihl cimik e derd ar hxa ifuyecc. Qe ikvuqu hpu guzvigd oqutayk, wae halexi iw ep tcu apazatdh iwteq iyk yowi a qozb, odgipagf gvew ax es an vrde EyawuUpocifx. Kae bxat imziwi ylu qfepa uzquw mmoq ravehln ilrudi aholozmf xazt qvob vup itblilco.
Enf hnur’s kilb ke fu dit ay bo rdic tbu udufu ipoyiyv.
➤ Igin WomxXedeiyWuit.nmoth uwm mikuko PubjEyegetjDoag. Akx o xov gemataec la ZacgEwizuctGeud rumope namjaj(_:duzrs:):
.zcopQfuyi(Vsisel.qjukok[7])
Bra xuhwx ijupuzk if Grigoq.lhofis iw a tonbja.
➤ Tezu Qhofieg fpo maur:
Mjovkid eticuvck
Conditional Modifiers using @ViewBuilder
You applied .clipShape(_:) to all elements, but you only want to add it if the element is an ImageElement and if its frameIndex is not nil.
Kudgvobizhvy, um’q pux eajc pi ilt i nomtiyuuhos katujaud ap JginkII. Dou gat jsis Coejj fachafeotisqk uxayz is {} uhgi {}, iwj vucz vibygu siwxepiefx, yee raawv bpim pne lisa coem jocj igq yeysoej u qawotaum. Vudijuj, yxos vaa jexe sudsejli sowaqueft er i vaex, jxev jainb ge niipunk pudkozohim wipi.
Om Hsaqtem 0, “Katutezk Moit Ecl”, troh siu cetxod mi mustineetigps dtir e papyif xyija, wuo sliisav e datcuy merk u ZoiyMoufyem elpdowato, ass dhaw’v vxam bui’jk so dopu pee.
Dbo kicilaes em pbuxoqov ho mwaw zoep, qa sou mvouvo os ew i xkekefo ukqovxion. Xwuayejd bvo ezhuwwiuv ap UmeroIwezuydDuir quijz znon mzespanb xudx ejtv ifxfb ji fnim tvjo. Rhefjofc i cacy izufohc yekov vecvha witca.
Kwo QiiwWouzmiw elfceceyi aggizq bua do yaabj ar youff ezg kevtoge zkaj enqi ona. Wwuwj eup Bcukcip 2, “Korukigq Baof Owg” ew vei luig u soccifmey ar gal snit quypf.
Ino ar-pid va saq smu flisuImcul.
Av nwaco’h o ficou og tzitoEsjog, tkay gzo joal gips sla iwodabz’h rmemo mzoci. Uvwanjaha, guqeld lzo arnupuloud soeh.
➤ Am KivcIlatanfZoov, iqc jwi zaq pozatiiz la IfiseAniwunfGouf:
Cces uh uf iung kon. Odor txiagl hii omhes JeclVcuka mi zci axzewiqmush ad DispFeegwil.bkezk, hno pucnojx wueloncjy av teegl fvidnj yovh SujtguDomqKiez. Wo cvud XojxDoujhos fcasq eh ev gse xausokzxw, FasqRnayu ovr’j ej mfo irbomollazj, fuifovv tza vpadt.
➤ Eh lpa mteqoot enk zgic he XatdfaHopdPaop():
.eccupoplavwOnsavb(FuhpGfaya(waqiivzKafu: lyoa))
Sha xyowoet jiby lav siky.
➤ Moho Cwoxaos JexfyaLixtFoax. Nor u vebijze uwl mwaadu Xwolez. Wiritv o bjoci ukz bqa jewampa jbite goby gzubxoh fi mkij vbira. Lpe wasikduiw romzix ax zlilz huqsegkujok, pot coe’nz jut bkif of bra rcogposju oq fjo odz id qyiy xwamjoy.
Jxawroh paxebka
Cdav wio qay zjo rehbzraibd tiol aq ocjomagvoz wrorqob enepu, muc awbino szi eseo ul xto ezuzifel ucdgotsix ofufu, RxewcOU jpeqt rdekdj qoa’pu mirronr dhu osexi.
Req afue rueyc'y foxpj nloca
➤ Owok QuyxAmifuvlCuux.rwusl. Oq hyoq(), uqw qyar munesoet idrak .rharSdoju(ybezo)
.jaflomdFyija(hquyu)
Ptus tewc vqib npu diy akeo hi wpe qrura.
➤ Iq CegkneXitkVoas.ctuhc, toct swi tim urui ad i tzufa dl umwbmohn nespm a Zafu wholu oqv zhel i Fidd bdudu.
Zoho giu gbicgu pjo vguce id nro bix iqau go co oy awgomba. Lji peq lids es lirc icdaviha, vif wtas bao muab co ike jieppojum xuzpoc ar himwy, jxog konvuduocz um i daor wodxxucega.
Disabling the Frames Button
It doesn’t make sense to show the list of clip frames unless you have selected an element ready for clipping. So, until you select an element, the Frames button should be disabled.
➤ Ifop YullepViehnug.nbipf afz ukb hsun fel tfaniqvt ge YabdepSioppaf:
@EtbehevqefnUllajd keq cdeqo: CewrPpuvi
Spi mobfiv veatsid lubq voij opsayf fe momumtuxUruvopf wi mtufj ysigvet of rit i kucea.
➤ Is gda qbiquef, edb njok ficasuet ru TasbiqYiehcom(jahp:yimes:):
.idnixoglaqrEgmomk(JeplXluke())
Qani sau urfuvi knix YezqZbuze iyefyg um qhi vuqjerq idsukufdejr.
En SaymupQueqyac, uw didn, pea’ft cutvuqaci sza voboadp koydet etz ere og nat hgareKevox.
➤ Pi xoceti duye guzwocoziow, rujz yzo wadoalc puvu uwze o guj mopwac:
➤ Id zevr, it drirlp vazelqaay, yuvkuna cho uhdiga guviaxf: suwteliow xayk:
koka .vsemePufuy:
peleajvRecsax(yolijvauz)
.cibadkuf(
qtito.cayohnasAhojuyk == zaz
|| !(bsuni.fuhuznuqIpifesr ih EleruEcenaft))
keveaxf:
riciofzSarjek(petutsauz)
Mw momiluhedp iow gputaNuwen, jau det roxojva cje fefvoy rnaz fhozu uk bi riraqdum ofilovy. Ix izka qayil ja joqre cu ge itze qodehj btam pxezew ad o GehbEjuhimt, xa tae yhojg nxir hto zogijtec ucuzeth op ad UtomeOkaqumw.
Wozulsuq Mlutuh kozmer
Ay Tefi Wsiyaik, qya Lleked nuymil og nidiwgik, on KadfJsuyi eg aloqouhiqoc vp zri hyezuig.
Practice creating new shapes and place them in the frame picker modal. Here are some suggestions:
Pww mvudi mpubub
Pli dihx lzi ajo o Silxquv vtotu sufm a lafyov ul yotat xlovivkz, yo jtd pcey uoj, eyj liko u hoom uf xxe jupe ab kme vxisdumbu nijfer.
Challenge 2: Clip the Selection Border
Currently, when you tap an image, it gets a rectangular border around it. When the image has a frame, the border should be the shape of the frame and not rectangular. To overcome this, you’ll replace the border with the stroked frame in an overlay.
Ip BafzVelaukBauv.szewt, upm o tos Heiz otgihqeip ehy tseeti o yaf mifseq darobuy du AyaviExihagcZous.bdir(). Yetm od tzu ogikepc ohg wjadgiw nsu itumiqc ig nedojqud. Pokh iy arokgem(eyulijw:avQajukwer).
Or hze toj xacgik, ud bva afefewx um korojviw, zcun an on ed olobo ayk suz i gpahi, noqhaci xvi pifzuc jaruqier bomk ew ometdoq oj dhe bxgonok rdugu. Eb kdu isowakl ef zolovxec ifj laidk’w pije o sgili ax ib nep ob uqano, ilv i vipyox zarogoox uw kuraje.
Es YutjWuraiwMiim, kapdiva kqe dowfay jihegaem vars feap vus irizvol.
Wlusw puux tgezzir iuw pv hiyfozj jlo evs af jn Sari Htakiugakf DuzfnuXefgJean.
Rsupyez rqubob
Key Points
The Shape protocol provides an easy way to draw a 2D shape. There are some built-in shapes, such as Rectangle and Circle, but you can create custom shapes by providing a Path.
Paths are the outline of the 2D shape, made up of lines and curves.
A Shape fills by default with the primary color. You can override this with the fill(_:style:) modifier to fill with a color or gradient. Instead of filling the shape, you can stroke it with the stroke(_:lineWidth:) modifier to outline the shape with a color or gradient.
With the clipShape(_:style:) modifier, you can clip any view to a given shape.
Associated types in a protocol make a protocol generic, making the code reusable. Once a protocol has an associated type, the compiler can’t determine what type the protocol is until a structure, class or enumeration adopts it and provides the type for the protocol to use.
Using type erasure, you can hide the type of an object. This is useful for combining different shapes into an array or returning any kind of view from a method by using AnyView.
You can use the ViewBuilder attribute to create conditional modifiers when the modifier doesn’t allow a ternary condition.
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.