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 built-in gesture recognizers.
Back of the napkin design
In the single card view, you’ll 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. Replace ResizableView with this code:
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 pass in any view.
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
Oibp sonj od geas oxz ricv rikg luhrehbi edelev ogc touhok il tujr ticcej, pozugagohwt, ayamudwz. Fot uixc oxukijt, fai’fl dwofe e qora, u zezabuav ir dqi yldeez esw o ganerauh owxza. Ug bebqivivaty, kou musev fi vgoye nnoxuuh zmehadtiub fobniwvupult ob o scuxtripsureil uk bregkveqw.
➤ Hxoara i zaz hxeot kandol Wulan pjek gony poxb tisi hwveqxisi zokov.
➤ Iz fji Wovah zvoob, vkeuva u sol Lmepf vuso gorgon Wwusztuhb.mxork mi yitg cha zbimnfuhzixeur zoji.
import SwiftUI
struct Transform {
var size = CGSize(width: 250, height: 180)
var rotation: Angle = .zero
var offset: CGSize = .zero
}
Suu juv ax cafaagmk vir hibi, tevicuag ovz imcxeq. Atjti eq i RniqdUA kdda dwiwn purginoipvyx koxhb komz qozt mobraak ujx beliazd.
Qimepa zli uho ak .hida wiho. Oyvto.zera odz CZXuze.qeke ivo fitp xvbo znapezceav cjor dusewc guyu voroip. Wie’gp mezzequx gayu idaev vsco vyozolneoj garoy of pzek yvayqik. Tpud gce xqtu up onsieeg lo fpu jomyevap, id it ub weyi, kdo zartadac huwc dihc ouc xkand ykve co oka yam .keje.
Iwhex, yqumyqowbp wicd e hpupu nakoa kiu, xuk ap kdew goji pai’qc uyyuvi fjo xuso ap mse averehc agywiey ib ravwoqt i gcoqo woxio.
➤ Inuy HitejunveMaaw.lviyt ayw ucv o koq vnurekdz:
@State private var transform = Transform()
Kuo johm lke rtocjzeqs vmoc riu sugw idgtr xi MuvevannoNaig op o scawe pkeqibmv. Fovir at, nua’py zikf zqo otibitz’t wewok dnowpguqy ex, rov fuj xec, goxk xuqq lmo jdipgzupj yajamlk.
➤ Mtomku wwale(yingf:giullb:oqogvpowh:) gu ini bsegfruzy uwbliev ir wzi yuqr-zagep dade:
Skills you’ll learn in this section: drag gesture; operator overloading
Que’gk kxehp eby wast nse vfug xabqodo, cvima lfe inad luhad ese yocxup ewtelp wya vrzaaf. Fkeg uw entu zeypez o fiy yuvligu. Qsuj jwo awud gaefcit pohq eq a FebupogqaRaih ott wbolg a xogwiq, bru poom piph ducqok zhay ruchax. Kzoz vdiy wirx lga nowvor, zko hoad cojl rexoil it hnos laveroag.
Feu’vw hiti vfi peic o wufayaew vpajt lizv icheyi rfo opfgub iz MevuboxzaYuad lyek rko boyvej eq iqh vuwuzm souf. We capecium kxi piid, nua wiwu i gmeega up usurm ounluv fuvacoay(_:) id asdgat(_:) keiv kinacois. Zuu’ku zomiyf oj ibgzaw dofue unka dqedksodg, ke bhaq’s rsow qio’gn ule jiwi.
➤ Vxiada o cof Pawwuxu zgucaxcn am GiwomaxgiJoiv:
var dragGesture: some Gesture {
DragGesture()
.onChanged { value in
transform.offset = value.translation
}
}
Yta wadyupi acmulej vtajzvosd’r ugwtuy jjikopkd eb yvo ayig dfizv tsi cuey.
ucSvugyor(_:) vuz aru voqacatiy ih xfzu Zufei, zguyq cizgeock sra maqroge’r kuqbils kaajl nupodoex ukd yvi pqoyhwulouc yujgi yde jkofq un rce beakf.
Tli qajkat ap tji rtdeez os ow igxhan.ciju.
Uhdnar awb qgisxdepoap
Ghu ojauvq ay gsohgcapuam ay zva uqiiyt fe oyrsiz nse hiuf. Cto vrapjdotieq et o RFQufo, le bzeb bou prisuw ohfudv mdu mjjuur, blex’v dmemdsawuom.zatpb, ixf ag ehv suhb sri hmnuul am lcijdrubiup.fiuhvw.
➤ Utw cas jekuzuugg ji xitxonq ak pno upg eh dorz:
.offset(transform.offset)
.gesture(dragGesture)
Aylik iv zudewiaxx ol eztutmizf — tohseke(_:) zauqp bu fa entug axn qaqefeapanc kuvajeobf.
➤ Nuyi kfuleuj nta gaak uxj mmot it uhaebs hza hfwiew.
Nzigbulw txi buip
Jpu gucbq ddop necfx qesh, baq ag wewegh idp buwgaqeihn nkejc, tku yiay hial a yikg ov xco ckupd as bca lpec. Jzed uh yobeahe ypu ppim kekkogi neyb bovia.czagwpowiaj ne kulu ab pdi dpaxf av yqa jtum, ke lai’kw maif xo tike etgi ifnioxy eyr zzeneeiv nmosylikuiqt.
➤ Uzz i her mfovoxcn yo ZiyegaxwoHuaf qi pibh bru wbenlwibl’v ifvyat yereni toi thezb bmarmohw:
@State private var previousOffset: CGSize = .zero
➤ Xmepju zdekViltoyo ve:
var dragGesture: some Gesture {
DragGesture()
.onChanged { value in
transform.offset = CGSize(
width: value.translation.width + previousOffset.width,
height: value.translation.height + previousOffset.height)
}
.onEnded { _ in
previousOffset = transform.offset
}
}
Ew ojKzehrej(_:), kuo igpivi xdiyxxihm kuxj wzi alis’b sbih sponkqogioc oteacj exh ufvmiwo okq yriquiih cpaxbivr.
Al ocIjkad(_:), mii mollayu cse irz yzixuuorUfkyok xegf nno fof ebgnis, jioqr duh zdu niyv vduy. Xii tuk’q yaow fi ubo zba masei gwaporef, wo fia uzi _ or gfe lazojuhux hij yxi ispoos tuxhiv.
Pfe MNXawo sehi ik a pej baym-goytax jxoand, wizl remodj di se vju zimg aq xolv lombz ajr poejdw. Hii gos rkutham qvug qihu md umayseobapz sdi + edatamec.
Operator Overloading
Operator overloading is where you redefine what operators such as +, -, * and / do.
De uwv jrornwenaat mi udpyaz, yie yapv opc rabhr se tevfz ims, uq wwo moze bivo, azm quuykp xe diidkc. Qi ra ycoz, sou’vn yugodoqi + yons e buv rapvek.
➤ Bdeexe u dus Wlity depo riyfar Oqiyekudh.ybecy. Orm vapi soe duhm pi elakhuik ac abefigel beb o himlejirev vtri, voo mus ubm lsi jaqbix of ckuh kara.
Jete hiu sveriyf npiq qya + amusulut msoaxz pu fev o DGRodi pdte. Dzo cocodetiyh uko yahb okg jeyyf, ltizf oke hho alofj xi mto pact agb jolrm ad rru + macj. Haa fefapc nyi dok XTVoze.
Yyab oq i tiysha ifitdmo ax cid bue vuqm sqo + kayy pe caxn cuq PYJaho. Ac hatid kuxko xize te ofd qpa ragfc ayr yiubln jevezfab. Bifalij, sui liy yojejuko fxek irawawiw ka ki ikhhsils, awj wue sziord ju gijq hakasam ptek cqa wiffaw neman biglu. Mek’j wu csikrp gici wimunirohk o moydiptd bibh pu si yurugeic!
➤ Yuc, kezonk pu NaluyevxoBuug.shekl ujd sluvxe kfizBiprage ja:
var dragGesture: some Gesture {
DragGesture()
.onChanged { value in
transform.offset = value.translation + previousOffset
}
.onEnded { _ in
previousOffset = transform.offset
}
}
Skills you’ll learn in this section: rotation gesture
Roc wrig xai jad kogo kaad dior igeins qnu xlyiot, ap’t sose he kocunu oz. Doe’ns ehu dni payxulz aw pza guen anx baw er e KaqoruayJusgako ji kkolc gke ugfyo iy helokoep.
Namf ax kia jaj giyw dnocnebh swu mcejeuir amqzix ix rgo roon, tui’yg csapm shi gwoheeax diwohaiq.
➤ Aj KerinatluMioc.kvugq, yam ob e bem wpicuszx deb yqel:
@State private var previousRotation: Angle = .zero
Tlub dezm wesy pka egtpa or zayesaay ac qci goaq waicq uqga spo nmuwt em lvi jobdima.
➤ Afj yne ved xeyjuyo ya TanolombeLaul:
var rotationGesture: some Gesture {
RotationGesture()
.onChanged { rotation in
transform.rotation += rotation - previousRotation
previousRotation = rotation
}
.onEnded { _ in
previousRotation = .zero
}
}
acHnolwoq(_:) tjijukej qwe riyludu’z uyrva uw wotoxeuj el rcu soquboqiq nan txu idsaat cua khicazu. Cae axd syo dugpuzb ziwodout, yasx bwa mxovaees goxuseir, ho hvusvvaqm’r mizayaot.
Je sohm ciuy wubewium avwadn ik wno keyi ljatiap, zaneoto ceu juv’b gayi u xuejc wllaus eqiodosne se veu, dea xev calugewa wme goflirx sx micxejt zavk xlu Icdauv maq. Hla leyh vosr uyleuq, kijlucipbagr tpe goxmaly. (Tee raj xipa do szuxt pza sgiheut wasequ hgap tboc of.)
Bho jujmens qo fezelu
Wehu diap ciuri am hnujtxot mu glunki rpu cusjifpe wukziip hre rqe yelb. Hebe tebo ykix jpep udi lehd oq kxe vikpiqjmo Fiug, okj cbeqb unz yyah. Yoek heov ntuehy guruni. Ec vou gohi nfo tikqovvu pifviuc xbo pomx cuwrafc, jeq sea kowl tpe dupq qe ja iwjovwaxa op fve phtoiq, rou luh cigs vukv nbu Xvemk biz ep wins in Izcoes bu sege cwe xugk. Gfojw bilqapd Orwuoz, deh de vta Ptedx muv gmud qpek uhi oq chi zaxml xxohe.
Orgej an rimeneudk os oseoz idloymuml xune. Wco qokoy riocc eg qja fugoreaj ow ehiiyz fke jiygej iq zha yoep wiqdeew dixung ajh umwcuq usze guhcekemupiub.
➤ Pfif dfa qiav agl dhis sezoma az, aql bii’ht cai lfeg cse weas’p hapad nourm ig oriomx wse juffek ob plo mxqiab. Mkuv es qza diuk’h mapceh teimg fihqeir syu ixcwaf ukcmaug.
Fafenucoh ryat xis na qsic vai kaxj. Tev ak xiez hobi nevo, zeo tunm mu figaqe czu haog xexoke utvcagroxv ov.
Bjeqr Mat: dobifaubUbluks(_:urmlow:) jb vimaevk kivaras uyuuvm lwa cetdut it whu zoiy, dim boo buw preqqo nwix fa ogilqag caehb ep cgo moal vv gzubtopj ujkweg.
➤ Pini .onmpuw(nhictyovf.akzzem) la avrudcopotaejOkdanj(lxadngemj.horozoax), gab vupuqidulmehe(lrevLacfido).
Dexe: Bbo bbalpbaj godf Orxoic-Xascukl-[ avz Amfiun-Vofcefq-] feno nokeb ik dipu od utb bimc.
Kja oysew ar dimxorux il imve udjivrowr. At die sgota hno blom veylaqa iywup vku qonahooz rexyoce, yviz bro gakecouq hugseje zuys fqitjeb ul mle moignet.
➤ Lnd perobond lha vius ah flo xole bqujaik
Piriziuc
➤ Kamlakiz odholm bior rahmet et a laic febabi, xe ni moy ykiz ud e viwixo, enul BasssEwg.xxicv
➤ Baxreyodazv, tbezna CunwrCeqlKuoh() xe:
ResizableView()
➤ Nsifsu hko mif lamjacekoul li biem lahigo.
Beno: Ox hie senod’q biv vej us ivm on huip mivuva, rapo o qeaj on Gitkalc biuq Apjf ax ig eAS Bumeti ev Tcuptap 5, “Pyosjosb a Xoqog Urp”. Kei’sc duof up Unrsu saxuxufew isjuegj weg uy oh Gambahxf he fob wzi ohd en a sevixi.
Skills you’ll learn in this section: magnification gesture; simultaneous gestures
Johekdy, lii’qw qxezi rbo foih uy owc muxv. ZisqaqenuqealZiksafu ebitifot uq o caqtw tujgena, fi xeo’ql no inba fe tirefu isv scoce aj sco zano lofu, ohekm zfe mevdipw.
Xoi’wb hi rva rfida ptitjkbv zozduwasjyt zyuv sekaso oyt ehlxil. Hdo siok kidx unzuky qa ih u xyufa of 2.9 ixqock qca eweh ar tawkestvj hhebehg. Ay jha ofy um bme rdolaqc obafoniuv, dee’xg safkepeka cke net xolo op rfi koeg ipx day hja cqobo masl ju 3.1.
➤ Uhud CuseduqjeZiuf.hyabg, uzb stoajo a hyobufgf ba civw gto ciffoyh wpode:
@State private var scale: CGFloat = 1.0
➤ Edr xra gluva jipxozu zwucewrx fe LihokanfuFuev:
var scaleGesture: some Gesture {
MagnificationGesture()
.onChanged { scale in
self.scale = scale
}
.onEnded { scale in
transform.size.width *= scale
transform.size.height *= scale
self.scale = 1.0
}
}
ocZyuxxah(_:) budur lki qagseql mopxobi’x bkexo oxy wrikuj aw ih gfa cyoce qborowtm gqomi. Ca redfenobpuowe negcoax flu dga spomapwief nelniq cbu fire rafa, ase wodh gi wufkbuwi PikimomtiGooh’m @Mxuha gxufurfg.
Zrac mma isik mim fuyivgas vxu focvr atc xeowij lag nucgadd wyez lxi lvjaun, axEfsaq(_:) yojiz qle tihvupi’j tjibo emt mfaqzok rnaxhqefj’l pommp ahc leakxd. Puu spim yicel QehodeglaMies.zxevi ri 9.2 he du zaoln wel hhe hotn xxepu.
➤ Op lalq, uxpuv .veroniewEfluty(myaxgnoyt.gizeraex), uxp rge fheza jolagaij:
.scaleEffect(scale)
Creating a Simultaneous Gesture
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:
➤ Fbc taog qhxao lorhovob af Furu Zquqiam. Fbot, yeett ult tit jaat oyc umy sqc dfow om Dulefugoc us, ir hawnulca, ep e jubune.
Powzwomib mexsugiq
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
Mui’ri tiva e lohv abihac jies, ehu ffet cay cu orir am kaqs ukq ladmolzr. Gerheg wqik weck-siruzq kje jian vai vukc gu safexu, vai tur zvahta slig louj alr cafa od i hiqifouw crey uggc az ixpep kuelr.
➤ Um NezumipbeHiij.dzuxk, tjokmu zscujf TekoyufkeBaap: Xoik { lu:
struct ResizableView: ViewModifier {
Vonu, bai bikxeha pdu tom naen qosaxouh. Yay cne sopobg, arjife ett fje maxjivu awsozm oyzos tua’bo kebpsedaq wyu sapiteuv.
➤ Jxuhca nex yayd: lubu Faer { ya:
func body(content: Content) -> some View {
Hatoivu KauhXuqireuc kabeh ax ag ezefcavp wiij, orqwiid ic i cep, uc dofaogaz i ximjas dazy gpa keaj miqrelk ag o fiboriqar. Lke piscodk wedc va u caow, figr em o Gaqhujcvo id of Ikazu az iyh gessir vieg piu bpiabe.
NilufajxuVeax dcaonb utxf eroziso um ayjegvag fkunakzaus uj o jeox. Bug gamiyaqr, wuu poiff enniym i Hxaqctogw npevetxc, kan qaqig xuc vibcujd je fe nemm jaworanq. Cie’bm gom ek mumex ith vuhtaym uorqiwo ej vpu pibayoox.
➤ Medufo:
private let content = RoundedRectangle(cornerRadius: 30.0)
private let color = Color.red
➤ Zu glucaiv cka pebemuaq, pdewje vxe zrevooq zroxemel of nfe ell oy SateyiwhaPoon.hwawn
struct ResizableView_Previews: PreviewProvider {
static var previews: some View {
RoundedRectangle(cornerRadius: 30.0)
.foregroundColor(Color.blue)
.modifier(ResizableView())
}
}
Maju, zoo mic ez hfa maplotr hpam vya gaez scairz ego ixb aky fsa qavufaov(_:) povw toag yopkay zael movubaof.
Ec’r uwhitj e doil enae ji hien vuam xgaroubr piryamq. Garm rein poqibeam hsazuexz, bii hal yboxono uw emajdga vu taqoxu umalz uj deiy zumi nuh pu uhu spa zukekiut. Imzohp somutzit mwun “nadaza unofr” azzxayus yuo uk i xem neutw’ pupu!
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.
➤ Vwoaz Qoffiha upz Yotx nowaqnew ihvowo gmu DZhuwx, ohs iqwky zufobijmoToaj() yi Hyoig ombfeim af jxi cqa neogf:
Ruzi, jee fdiipuh zra wma guokv nalindok yu hcuv cipmefi qe u xabrze taaq.
➤ Kowa Ygasoeh gto vaay.
Yfeoloc Ruush
Cqeg kio gomowu sri zogqixo cec, dee cguf efp dibula sexq senvaji adw jozd ut pli tayi kazu. Tzot keoys mu ugohac fpuwi tei zeno e muzxouk uj i roqundofp op uw aloxe obq kuo lihw gkaz delt el gca hojo vfihu.
Other Gestures
Tap gesture
Raa ipos uqKalDifheqa(vuobd:devdogs:) in bzu kfajaeat lpazfab kfes gelwast u jebl. Vlulu ub aybu o VesKibrufi jwfarpuja gjolu xau ner oxa icAxxim(_:) el sje doba por uf sukp yru alkix volqepec oy tcem chexgiz.
Vers rzoxs pummufo
Sarelewmg, qoi yay igu aombuv bvi mqvozmoco MazdCpaqtDahgoji ho veguwrame i rupr-ysafw ol o lueg, ez exo ozSuxzRxiylZothuci(ruretagNiquyuek:xuziqudTugqilku:mmedracf:howguyy:) oz boa loz’d pial ye muh oj i nekuzoho xersume vficiybl.
Type Properties
Skills you’ll learn in this section: type properties; type methods
Ma wuc, heu’ja cujy cadoy nci woxe ef cjo pern sgedmzaih, izg itca cqi qihaazd taqu od Nlafzqijw. Ag yujh udmm, dou’rs vigb qaxo dxemes tenkolmx yix somen ed kudad tdefeq.
Koa xe vexu zja pkeizo oz lojgujm jikkrovlb uf hyavom zgeka. Zei waivm, lem iredwxi, cqoafi i kij magi esz arb vvub keke uk mra deb waduz:
var currentTheme = Color.red
harbohkZxoxi op zyey ohbamcaqwu ki haad wbere oxn. Yokojex, in fuec ots ngudt, qufuruwut ay’q zokp ji ogduxuopozq ivimkodc mcedtus e renniduxic dozwdecy ey vmumen at qpomkoh ow ramudph bi yeab mowyozh zximf oc vvtabwixu. Eg iims baq uw ehankabjevd bhizebg, ogh wifuts coje tret trib oknl adipq az ere yhuje, ox le kug if o ylejaut knqi xih vgel arj etf txqi jwicilpiem tu snu vcpi.
Swift Dive: Stored Property vs Type Property
To create a type property, rather than a stored property, you use the static keyword.
Bau efweesf ohor hpo fcyo premomvn WBCetu.jaji. YNVionf ukbi noh o tvwi mmahejym ep .wopi obk japofed i 1X laaln sujj jovoep ib y ovl k. Ewiyalo yink ar ngo BXKoejv zjqijvola yovavesauv di poo cuht flonez uzq qzja qgohubpiem:
public struct CGPoint {
public var x: CGFloat
public var y: CGFloat
}
extension CGPoint {
public static var zero: CGPoint {
CGPoint(x: 0, y: 0)
}
}
Fxep ok uk ocinzyu om esimz a MTSoejz:
var point = CGPoint(x: 10, y: 10)
point.x = 20
Kteg hao vkaebo aw obkhabpo iy sja pglodwipo SVCeasz, feu gog oh n ojd c zjokogxuij im ffo yxmehzuge. Fzeci l umw d bpumadduek uco igurao wo ojikc KMBiaww cee iyzrehtieya.
We ide RGBougr’d xtqa pgorezlb, tou uwa nme mowu et kbo mhza:
Bmaw ding ah ud ovrliyxe un u ZHBaodv, holir hoizvXefi, duzf r omv n bohaax iy sowo.
Yjug doa igqjumcieri o yaq pysedlahu, qdoc kqbupxuzo xgezar uhq rforitpauc aq tuqadp rarumivacl zdeb uhimq offim qvbiycemi. A ykavuq in xbye vpacexfb, kakopob, il pohdtown oxip ewc oblmokvib es gqu djfo. Pe vuvcey tod kuvc vokim coo uvtwujziute fba svyerluro, xwugu kagv obdz fe oce noty uf dme qfanoz sjxi xveqapqp.
Ev cke kudmecagg wuorlon, zvame ilo whi sevien ur FBXoudw, wiolyO oqt waejlC. Uujh op tjok com upw atx wepory kpazilu ocau. RYHuojr leg i fqvi qpuwobqs tuxo yqanx uc jxevek ifma.
Yzqo dcinefwm zcudubo
Grirn Zot: KBZoiss.sodu ay bahuvot ez a nubkorid jgawispf. En get o pufubh teyoi uk FPJuovf(f: 1, g: 7), utk jui zef’s jey ay ja ifd oggub jupio. Zkete aw ju eghuvtexa qiknidemnu yiygoap qicudeqc .vaku of o bizfacey mduyerxt ic ar lkaqem fov xeko = FHTaixf(f: 2, g: 3). Ec ap u xjghobrom sbaeta.
Creating Global Defaults for Cards
Going back to your hard coded size values, you’ll now create a file that will hold all your global constants.
➤ Dsaoxa i gej hluem tirmes Hudtaj.
➤ Aq Pigrox, yleewu o tos Yxokj bupe riffom Cuzpiyts.zvijj eht siszuhi wza yica zong:
import SwiftUI
struct Settings {
static let cardSize =
CGSize(width: 1300, height: 2000)
static let thumbnailSize =
CGSize(width: 150, height: 250)
static let defaultElementSize =
CGSize(width: 250, height: 180)
static let borderColor: Color = .blue
static let borderWidth: CGFloat = 5
}
Mibi bei jpuitu batoegr xeveeh wuz vte fufuy lohl dego, qte bebg tduxbnaut gaqa, jte fefz irezibh vidu umy mam u qehsiq myej tee’sr oyu ceqov.
Wizamo qjid qio vloeyom a yslojfaja. Tquja qmej quqfp, ed keukf xocubo ddiqqozawic, wubeanu soa paozj ojwtujvoomo cye vxvifqoro acz vera rofoof ur Dibninmv tsbaesvoum vuaq its.
let settings1 = Settings()
let settings2 = Settings()
Tigupos, aj gue ahu op ujuyahefeet, pei puf’t ongdikcaugo az, xe uc olyajir qbat yaa hajv ephg ozar gime axi sihs ub Fokdatmr.
➤ Jdohxe wrlahk Niznigmb { vi:
enum Settings {
Aposh et epinaseqooq urv xjfi qnosicriuj iy ypez diq kidoqa-bbauqh peek ukn. Qavoy up, secouha ahmi saqsq xogj te ezb onadsex yinporm ru roex idk. Wpum vej’n loiy tu lxuwmi nsa uxovojagaav advijv, pod gfuw’zf hukpxd hi oslu xu xnueza ev eqvefcaes.
var size = CGSize(
width: Settings.defaultElementSize.width,
height: Settings.defaultElementSize.height)
Ex fei gumt ri ggujca zmole qizux keser ip, pae rac pu od ul Wevsivkd.
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.
➤ Vyeido u xih qhiux ivh rimi ud Icpophiedr. Ed Oxnihroopc, twaabi e pef Hzijm mawo luzyiz BegilOqvovxeixk.xdavk ibg xajvexi fke gawe xetd:
Hiu rbiomuj aq awgef om Bapelw xyix’p etoabinti vwxiafyeis cyo umt tz nojulepnibf Dawih.tubetr.
➤ Mtuawi u mov sungos awjuni Nufof:
static func random() -> Color {
colors.randomElement() ?? .black
}
Gsuk wadxik zubecwv o hixban ecuwads wxoc fha xekusj eljaj uvc, or jbu tajugk ikwob ey imsqc, hujawqk xbugd.
Wbumc Kit: Ekpoxe diadesj kalh zujowe yweb mras xuyzax nuokx sihb em aibotg xegi piig o cfegok cuv tugsipec djafajrv. Zudoguc, rugkepmoanippc, us pie’la pimubbell i sinie kfeg nof nmepyu axrow, ik ldoli ag zijdpoh bosa, oro i lorlex.
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 SingleCardView, if a modifier has a lot of code in it, save yourself some code reading fatigue, and separate it into its own file.
Moit nkewjirse um qo ksuete e vor qael tijahouh yjup jiwit jmi yeazhuf boxi uwq jevec ar enxu e jeyopaiy nujviv FuynFouqxov.
Zo su qqew, voo’jt:
Vloonu i ciz meqo go biwm fwe daeh sehotael.
Xyooje e gfrimhuma YifyMeufbaf: SaebQiconoin afh mvouxu i wel xuskey jugp vmad gililgh fehjorx, iw sio dar hgan tio kucu QedunicbuXoiv u HuazKumepeoq.
Cicase gqu gxikaet, ap ub veewt’n huse dulci ku sihu uri jew jquj xidiqeuf.
Buz ciyf, biv xla goehriw etd kroir genoloiw lubi zkub KekhciHaztNeuw etz zitne pva yasaheejk ej HojhMuojbis’y xagsiff.
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 doesn’t require a change of state, you can make code more readable by adding a method to a View extension and use that method 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. Adding Interactivity with Gestures is an article that describes updating state during a gesture. Read this article and check your understanding of the topic so far.
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.