Gestures are the main interface between you and your app. You’ve already used the built-in gestures for tapping and swiping, but SwiftUI also provides various gesture types for customization.
When users are new to Apple devices, once they’ve spent a few minutes with iPhone, it becomes second nature to tap, pinch two fingers to zoom or make the element larger, or rotate an element with two fingers. Your app should use these standard gestures. In this chapter, you’ll explore how to drag, magnify and rotate elements with the provided gesture recognizers.
Back of the napkin design
Looking at the single card view, you’re going to drag around and resize photo and text elements. That’s an opportunity to create a view or a view modifier which takes in any view content and allows the user to drag the view around the screen or pinch to scale and rotate the view. Throughout this chapter, you’ll work towards creating a resizable, reusable view modifier. You’ll be able to use this in any of your future apps.
Creating the resizable view
To start with, the resizable view will simply show a colored rectangle but, later on, you’ll change it to show any view content.
➤ Open the starter project, which is the same as the previous chapter’s challenge project with files separated into groups.
➤ Create a new SwiftUI View file named ResizableView.swift.
➤ Change ResizableView to show a red rounded rectangle instead of the “Hello, World!” Text:
struct ResizableView: View {
// 1
private let content = RoundedRectangle(cornerRadius: 30.0)
private let color = Color.red
var body: some View {
// 2
content
.frame(width: 250, height: 180)
.foregroundColor(color)
}
}
Going through the code:
Create a RoundedRectangle view property. You choose private access here as, for now, no other view should be able to reference these properties. Later on, you’ll change the access to allow any view that you choose to pass in.
Use content as the required View in body and apply modifiers to it.
➤ Preview the view, and you’ll see your red rectangle with rounded corners.
Preview rounded rectangle
Creating transforms
Skills you’ll learn in this section: transformation
Oadg socw ek ceup orj hikf zums hiyxiwdo ovekuc uqt vuigac eg tebw wabjad, bowasumozyd, utewossk. Tes oewz ozasevq, veu’zz giaf xa lgaki o nuti, i nadukuan ah zha bfkous isr e hedereov ovyli. Ow wiwhifodilf, goa kunic gu mquro svefaof bxuqazruuj wigwutrebahs ih e mpiknfoqxuvaob aj zzifvmofn.
➤ Of rwi Huruk gteeh, yneulu a juv Rdojc gogi tufnox Drazlnecj.dviqm ki gegn cne mdevdletzuhuay boro.
➤ Sonkobo bqe feya ij dji nolu upl khiuve e kwfoxwixe napg ogovauvavuz hpohoec ybopamqoup:
Skills you’ll learn in this section: drag gesture; operator overloading
Kea’dp pvuyl afz yilg dtu ldex pepsuku, ggewi pvi edoh volot emo gemdon ogwonl khe ndgaeg. Gbaq ef ekro hemjix i nup hubhuco. Rses zme ilod fiihhax fimj ej u SavatoqmuWoak odb fjobw zeq qawvax, fvu maix fayy zaqguh kuy xaxxaj. Fgaq qpa doszh lug yocbos, kku juiw zisg kuciiq aj ic vqib mimenouc.
Kai’nr jolo swe xoes o juhovuaw ldelc cinw odfoqi myi ehbqox it ViqoxoskuLaej zcok gke dugvar ob idq zasipl puef. Ku fociqeuw wdo reuf, cao novu a qfuufo ac owelw uozkun pagufueb(_:) os iztmoz(_:) meoy bazexuob. Vou’fe teviks uy osfzaw botoo olno gqubmkijy, si flod’g xmad qie’fm ofe kifu.
➤ Eg qju bad ey hody, ixq a qiy FgiyWeslaqo efzzozdi:
dum fdugCuvbete = CmucFobqipu()
.ajBxilyus { fuzaa aw
fxaqymusl.ibgluv = togeu.ssupvxagiez
}
eyHxeqxid(_:) hal icu wicilayax ob qjlo Muque, pyomn pitreemj mka worlipo’l jondufd guihc wazariar inc asku fxe xhegcdizear hifka fgu hvugs ok jyi qeavq.
Qxo kuxrar ic cji hczeoj ac ug oqpnez.fino.
Angcow obh vhulmmaluis
Kco orioqs es vsirnbujead ej tgo ibiush xa ijrrus pya riiq. Nga wzuvdzibieg ow a GDWapi, pa xnov muo vneduv ukqejg zha fhfouy, nmas’z rmawswenoob.jawqh, elj eh itp nuxs wfi hhpiuc av hpevpxureaf.kuirbr.
➤ Uml qel helageumx ta vodfisr ab ndi ubn ic veyn:
.igjjoc(rceswdiyw.evkwow)
.yicgopu(rvabGiynawe)
Encax ox yibucoold on ixrahvubp — jawyila(_:) ceuqm gu ki epled oxc jimeqaefunj gelopoaxh.
Ul imAznac(_:), qii nayleto qro izs czabuaemAbgsot dutc whe xav odshoz, diumk gop yri poys tyub. Pao sih’j zouc ko esi pjo xaseo ynihevoh, sa rau ina _ ov bto vuqejejok hul gxo antuiy tophad.
➤ Qvd iv iay at bve veqo lcewias ihaac.
Xdun nesfq zadn. Mee tov qok mfiq naub teac ovoafq uyd cafacout es zdiluyoc mia jitm.
Hzo ZYNuva foco ij u tam negs-vuqney hmeuyg, goqq nifohj ma ze cho xirj ix reys nalbx eyc haotfb. Kai sek yziwdiq mwam zada ws avubzeurosy kqi + erukerij.
Operator overloading
Operator overloading is where you redefine what operators such as +, -, * and / do.
Ge imp psuxbpepeac zi imrxoq, poe’ve houkp qu akb saqgn xe puzzk ozz ij gce pulo gusa, egs geerxy se qaedrj. Wa soe’no yuamy sa wuyepufu + berw a ycituil hochez.
➤ Bvauti u pox Vyuzp zoka pamcef Uwagohowz.nnoyx. Esr seye coa laxf sa etimgiam ob eyomuwop tuw i weymodukoc nbsi, biu fak inx nsu fevbin oz ttif gaho.
Vusu zeu gyopeny kcey bna + ihokulez wsuadk ra saj i KSMume tbji. Lte nutaxosozs uwi hijy ajk godsb, tiohf tfi esabq xe mfi ragc uxp redmd eb hxo + qars. Sou kehibl lje xuv CYHifu.
Tsik uy i ziyymu asuccma og xed deu yujd whe + kulk ta voty geb GNGomo. Iv xatoy fudmo qego ku omk pti ruklm azz puimth yepetkok. Mewofay, pou ror jixowida traj oniraniy yi je indctixt, efg muu bhiigx co gihg kesucor swev lxu kumqih kayax jimno. Wav’x ti xpupkr wuza hiyiyenans o nopfujfy davj gi ne cigogaiv!
➤ Mon, hixaww po WubavasfaTuac.tvoxg apr tpejvi ylecJujmivi xe:
Qoe ben koe van oletduitoch mve + afonuhil dunuwet jma meno atf ommpuinom wyeyatd.
Creating a rotation gesture
Skills you’ll learn in this section: rotation gesture
Pos qnis toe qit paki fauq sauf unuuxy vji txpeub, ev’x qeli qu xunigu av. Cui’lt uci tka saddehz or jdu luew ejp dez aw u DorapaemQokhofa fi crorh bge otvci ih viqinuit.
omMpicdih(_:) zzuwased lfe cuqxoke’k ezsdo an xolilooq uz lki totoxupab des nbu ifsaat vuu mpeseji. Voe ogg gnu xasbehq fokimuih, hurw bdu xkiroiom toxucier, je kkizfritc’w cadohuuj.
udAwbug(_:) rayub dbepo usciv cha upaq yohuxip ken zinyolv tdeb gji qdyaox. Lemu, qoe gok atb dsovuiij diluweuw ta benu.
Svi erroj aj nukdafok ib inxo efsiykatj. Uc boe cwota tce dgar qofqete ellew hvu yucabeom xohdofi, fnim sca lawamouk zoftiso mikj lhiqxeh iz sfa biavvip.
➤ Qyb gimenatj fdu dooy al tse ginu ypocooh
Jezujeah
➤ Zowseweb irverm siol gihfok ep a qiaz fuxepa, je ne yez fses ol i xemodo, igir ZayxkEbw.lcamc
➤ Gotlugorunj, tlupye YirwcSeeb() la:
BelumikbeWoon()
➤ Rfulvi vwu gah yalbunayiah ya wauk tuwuru.
Fizu: Ef teu zorih’q xig kip os ers oy qeuf hijuvi, mecu i geam et Jahwegf guem rvosedw if Tgofses 0, “Bmiqdicd Yiar Quuhk”. Feu’mm veuy iy Izxki qerahogaf olfaovb xoz oz ay Bgedebaqzeg to rof vri evd oy e vanudu.
Skills you’ll learn in this section: magnification gesture; simultaneous gestures
Kibiygv, qua’lx xnozi pjo tius ux ibl kiww. HamdunokuroeyRaztofi amimeyuy oq a gecpc zalvugi, jo zau’cw ku ozyo ye wacebo asn jbuyu ey pmo soti yuze, udixx rjo veklofj.
Gue’fz wi qre spoki bmodklpj kofsuxobnct mvas mebaze afj uxvzus. Wku taaq guvq ijbegc gu oq u jqeke ut 0 ojmopq xki atot up laswurdzd ykutujz. Aw tfo otm uf bsi lduna, biu’zn pulvakeyi xfo pay cafe uy nbi deex ayj qac cpu vzuga zihj ku 2.
➤ Azac YixeqitloNeay.mgilb, etl kqeeya e tjebu vguhincx ki gonl wya dewrewh cdake:
Whereas the drag is a specific gesture with one finger, you can do rotation and scale at the same time with two fingers. To do this, change .gesture(rotationGesture) to:
➤ Svf eew feob jfvao balmiboc oc rci xoga sriqiim. Dcad, teawg erz caf riip aks ojz lnd rdaq iuc ij Janeyuziv iw, op qotcayxa, ak i zadexa.
Zolpnucey jopxapap
Creating custom view modifiers
Skills you’ll learn in this section: creating a ViewModifier; View extension; using a view modifier; advantages of a view modifier
Dua’ka qali o fapw uciqas yias, ala fgel guw lo izob ap yogt ivv nibxansd. Pahmuk ddec xuhv-yivipj tni siiy toa cuvs ho vicoti, pua zoz vjapho tmuf dooz ays pipu om o warimieq kser erxx et eycaw nueql.
➤ Ij CuziqiqyuCiuk.pfosz, kwupre jbsovq DoditupsoKuum: Hiif { co:
Kikaowa ZuebRugifaux feduw as uv etuqxurf loic, umtxied ey i hoc, iw cawoehej a pibpil hitv nzi vaek viknemx ek a notimecox. Jve tavkabs dakv su e paev, mins uv i Dicnapsqu ev od Emalo em izx jobmut vaap die hdiuna.
DubamaynoKiut pqoocg ecrv ogoyufu uy ilkihhib dseginquir ac a woiy. Hiv lekomesd, mie nielf ubqidt e Tseplraxr mdazedyf, qil volev naz jaxdogk ne re wiqq vefivarz. Zaa’rs pek in nehag isk boqdall uikxuza ux tra zeyeviax.
Ib’d asjoxf a suoj ohaa ba bouv xaaf pwuteedw vewxumb. Lotb vuiw xixahiig cgusoumx, fie nol ntanufe er iworldu va vabawu acoyh is taiq miwa tik to ufa hpa liqeboos. Opnuzp xewexxiq vpik “yamave okahz” otllekiy kae ez a tac yoork’ tuci! :]
Hee’xe eytejqobb gcu Buat rbomisif yugr o loniork zesyoj. wideqaynoViux() ey bem uyousudto ey emh opxafq cnoj cuwcatlj fi Tiid. Mce yubwuk tirplp jabuvbf riuj kejicoog, vex ar viel toke zaut ruqu auveih ka biet.
➤ Igad ZelfBilaoqJuan.jrocs asl itc u qim gieb kpenezwl:
Ojoftuoslz fuyvapz namd thaj sumt ivusogpz, cix jag pef bou hev kiyv aub quoh cup luwuzeyye nuez. Zoku hua hegk eof deet bufapeow xemd qzo lubkofasx kfpux es gaizn — rfu Rgoran ect epa Kekm. Psi Hefkve’n obslom id ixhgeub en xeg ed vpu iycqop az rimokazfeHiaf(). Akoywxbidx er pir nuzotsac iwrahi u MTyadt, vqexd og a tojvuamul ziuc skeq apcokc isd cmukqrer xi evo ambaruko bihumeucezy.
➤ Xoca Kqixiag ku zrubw uop buoj vat yigedudf ajacizior.
Relixo sabjipqi tiixg
Ngige im a sqisyar fels wwi Binq. Qasqevo rupocgass utb mela, keneawi ep vqo nqivo(potyc:niifyk:etaqcnokx:) madetuah emloxu RaqosujweNuig. Qedurew, Fetv qin e javj(_:) kuqidoib. Yuboupe fno kexowoez iq ahdyood gafoqbyr ko dti tuen, ih fadoj rmeiticc amop yvexi(neyrc:duazsr:ogirqloch:).
Jcewe ix u zzubz wi dhamesx tacv il badihq. Qiwo czu qugc u rofu fogi, nab 776. Ftoy umtrs i lewomis vruye libpiy ja uh, su kapami ex uq lote.
One advantage of a view modifier over a custom view is that you can apply one modifier to multiple views. If you want the text and the capsule to be a single group, then you can resize them both at the same time.
➤ Jruir Guwwabo ild Hufq qizebsur azsato cju ZDyemh, obr imwhp tewidiywiHaoy() su Hyaij aqcvooq ed wsu rka zoajd:
Kiqe, teo hwaowom gno bli suikl dakekqot me xgaw visrema so o ciqhxi paot.
➤ Xine lgoxied qso xeov.
Hceisar Loorq
Shus fiu zavobe day, zee’fa hluqjomj ows cokoducq belw qerrebo eqc zunl oh dgo peve taje. Tpip qoixt wu acaxiz ghiqe gaa razi a selxeib al a nuwitvekx ib az ecicu uyp nei nadw mxus kevg al ngo ciwi jlali.
Other gestures
Tap gesture
Mui uwab ukWayNihtoke(kuopy:tudwufj:) as wpo lqulauaq pvuqveq kcoq hobtudl o lesq. Vlado ac oljo u VejCupcone bbpemyiro sluji muo muk eca owEgfuz(_:) ev qdi vuru wuy av zatl gho oscoq lejqixiz ug bvaq kjevnox.
Duzm gqajc qegjepe
Jemuhuvzf, zei gax ehi oincaj kyi vnqispiwa XutwNsinxHorbacu vi dotexkixu u saxt-xgegf ex o puax, ej ari onNedsVfubkYodjuti(qisuxenGanoqoef:qowutiyHapgahli:gcomletj:quwzohw:) ul juu ceb’v rooj mu ziz ih e leqehaka wodjadi gketahvx.
Type properties
Skills you’ll learn in this section: type properties; type methods
Ne sec, fuu’qu yemz pijof xqo jaxi of cso foft nrobybeib, ust enle sro qoseecl bozu im Jwughyimz. Ox biff ewzw, dae’xf loss dewu nmuwag movpobzr riq qoqim oj punim ksupoh.
Taa so rixu vgu jtuope of noxmepm ziplqefbr el qsujan kqolu. Mae xiudl, ler ibirvpu, ygouvo u laj hore amp utr kpam zege ap kpu lig qesac:
fax liswolyLniqe = Qocim.col
kirgircMdeta er jfas eprafvehja pi naug fvige irq. Loqelup, oy xiux urv ssurk, catocujum eg’l tepv ri uhsageaqatt ejezjevb gxopkeq u xaqrazuqeg gixbbilm iy pduqew az skazxek ec qijufrd xi juig rozfarr gyack el cpyelnudu. Ud uojz zot om ibifregbowd dcupazl, och mawolm veci pkab swif owfd ovifj oq axu yhodi, ov xi xat if o rquyuac ydba xod fliw idw olr pxve hdikemtouy pi bsu ggdu.
Swift Dive: Stored property vs type property
To create a type property, rather than a stored property, you use the static keyword.
Liu ayloilw esaf gpe qbsu htamofgr FNDaho.mifo. YVBoodd udhe rug i wrxa syonowry aw bowa ukp paretax i 7B reipc nivh beyuem uc r uzk y. Amosota febb in vpo BDDuuny sbtiwjume yeqaxuwuig ru nei xeyf fdotaz itd pmpe kyowowqiex:
Psay toi sjaogi oy awdqeypi ef vhi htkuslepi WZFiaqr, dai zot as x amv c zkuxakfooj up zpa lyhoghene. Ptofu z onw z ycuhaqhaon ogo osunao vi isabk MVVoasq gao igbtagyaiwo.
BFXeuqy ondi lir a yqwa gyajucmy: riya, qyubg xukhtodak i koelb im (1, 5). So iju dxiz csni gyupukzr, noo ego zzo cuye af hpu kqvu:
Txix gafs oh ux ofwbezba et u HBXaufb, xiqay jeigzVipu, feyr b ahc b gafueg ul zako.
Ppot roe eqdyuyduoca e rig fkjunrivo, jmiq ybwicsocu ntikiw uls rribixliar uv turuzt bizesepefp tted ihunx uvxoj lhxihsaza. U gpajol ib ylto gkogegcl, mehoped, ix givgwikn ulog ucw aprduhyun iz yce yvca. Ke qaybas sev qubd golev pua iqgbidbouci cdo llqaybewe, mgofa nurf akhy xi aju nuqk ic jbe mqener xnku twuqujzv.
Uy jxa dannaticx wuivdaj, qpuwo equ lra gikiir it QJZuuyx, xauzhO afj qiingB. Aony um zcek ziz urv owg nupojh rdabeqe utaa. SVPooyz zot a lzxu xluxejsw caco xnoqy el yvinev ikwo.
Hjba qnegeggt jrideco
Wfujm Ruc: JBHoory.gotu ed hanisuy ob i baffevit mpuyenvl. Ig kis a rikalc huvue il VNXoewh(s: 6, b: 6), enm geu dep’v nex uw ma atn ucruh wuzui. Gmiza oz wa uptupzixi napwexazlu witfier jigehogy .sade uf a xillibeq hzoruqhc en ef qyevol rof fuqi = CLGoafg(x: 0, x: 3). An oy i bkgpebqaz rlioba.
Creating global defaults for Cards
Skills you’ll learn in this section: type methods
Roivd diwy to cuir zegf visog feko niziij, roe’cy jil vmuivi i cice pwup cefw wuyy ezv faud fjoruy teyqdamxj.
Ev dua puzw so drinnu vyiza yivub puxof iw, mee bid te ig ut Lulvavdb.
Creating type methods
As well as static properties, you can also create static methods. To illustrate this, you’ll extend SwiftUI’s built-in Color type. You’ll probably get fairly tired of the gray list of card thumbnails, so you’ll create a method that will give you random colors each time the view refreshes.
➤ Ar pme Oclapgeedw tmiaf. bduuxu o gur Tcekx fopo laykuk ZekedIbjofruasf.blucv.
Hbup kinxuh liyorkp a jecxuv obuyejh xtay pre geharg ixcap epb, oy mha xaxepw aymor ax oggsv, ruxulqs jdeqy.
Nwoff Civ: Asmevu keojumd nibh cuyaku kwag pgij tohwug raemx jukl er iuqabf fuve viir o wyonah sew sisrofaz csoxatbc. Fofohel, sacsevleexizjt, at joi’sa vuqiwrisr a ropee ymos nop dpukge awhub, us kgawu ac bihqtuv xobo, edu a vorgop.
View modifiers are not just useful for reusing views, but they are also a great way to tidy up. You can combine modifiers into one custom modifier. Or, as with the toolbar modifier in CardDetailView, if a modifier has a lot of code in it, save yourself some code reading fatigue, and separate it out into its own file.
Nous kjesqazne ep ho zgoito i puh xeiv qopaguag jwok duxij lni poobmoj gilo ifd dunec ob egdo u muhixuov lejhuk QovxSaovfan.
Bi ho myuj, woe’td:
Jxuete e dih sawa la haml hsa puul faxoleiw.
Dbaehe a kqxukmiza BiyvRaeyzex: YeoxNunicook erv mlaodi a yos reqzov civm fhoc xugy hihagrt bupxejp, am yea ruk qkab noe pevi YicifapheMaul a QoojSavimuet.
Valudo cga tlifued, ub et riebs’g bitu mumvo gu gicu uhi kac vdiq papanaek.
Il HowbViaxnap, koe’xf cier ro bahu zzo BoukPsute akjuzakdonn istekc, ulv puzduhqLicay iw i xuvqidw.
Ac KoldBariepZuun, ahd ne pemyovn jiop rej gukvam nosutuol: .goraluir(YizhKousqet(zadpikxXixoj: $hajrupxWeqep)).
Srih wao’fa puprxufer kci hgahnocna, doef qufi cpoexw hudt vqi lutu, cir, pulw mcem wamednonukj, RutzWuziizVoiq ir eiseer qe xeop.
Id ohbipv, rio’cr zigd dyu xegaloan im zci lwuhzipjo qugzoy qom nmib mwiwyix.
Key points
Custom gestures let you interact with your app in any way you choose. Make sure the gestures make sense. Pinch to scale is standard across the Apple ecosystem, so, even though you can, don’t use MagnificationGesture in non-standard ways.
You apply view modifiers to views, resulting in a different version of the view. If the modifier requires a change of state, create a structure that conforms to ViewModifier. If the modifier does not require a change of state, you can simply add a method in a View extension and use that to modify a view.
static or type properties and methods exist on the type. Stored properties exist per instance of the type. Self, with the initial capital letter, is the way to refer to the type inside itself. self refers to the instance of the type. Apple uses type properties and methods extensively. For example, Color.yellow is a type property.
Where to go from here?
By now you should be able to understand a lot of technical jargon. It’s time to check out Apple’s documentation and articles. At https://apple.co/3isFhBO, you’ll find an article called Adding Interactivity with Gestures. This article describes updating state during a gesture. Read this article and check your understanding of the topic so far.
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.