One of the tricky parts about UIKit animations and the corresponding closure syntax is that, if you aren’t using some of the new APIs like UIViewPropertyAnimator (which you will look into in later chapters), once you create and run a view animation you can’t pause it, stop it or access it in any way.
With Core Animation, however, you can easily inspect animations that are running on a layer and stop them if you need to. Furthermore, you can even set a delegate object on your animations and react to animation events. In contrast to the completion block you’ve seen in view animations, you can receive delegate callbacks for when an animation begins and ends (or is interrupted).
In this chapter you’ll continue to work with the Bahama Air login project and use animation delegates to make your animations more interactive.
Introducing Animation Delegates
CAAnimation and its subclass CABasicAnimation implement the delegate pattern and let you respond to animation events.
CAAnimationDelegate features two methods that you can implement if you need either or both of them:
You can either open the starter project for this chapter, or carry on with your own project if you’ve completed the previous chapter and its challenges.
Your first task is to make each form element pulse once when it reaches its final position on the screen using animationDidStop().
Open ViewController.swift and add the following code to viewWillAppear(), just before the line where you add the animation to your heading layer:
flyRight.delegate = self
Then add the delegate method to the class in an extension to your view controller:
This simply prints out a line to the console to show that you are, in fact, calling your delegate method.
Build and run your project; you should see the following output in the Xcode console:
Okay, so your delegates are being called — but how do you discern which animation stopped in the code above? Remember, you added the same animation to three different layers! The following section shows you how to manage this with key-value pairs.
Key-value Coding Compliance
The CAAnimation class and its subclasses are written in Objective-C and are key-value coding compliant, which means you can treat them like dictionaries and add new properties to them at run time.
Joa’xl ogi cron xojlogocy xu ezcolm e cani ja rqa hytWijzd ubiqeceig yi dnos fia sol aqerwapm is iox uj xki panj uh ozrax umruva oqufanaunx.
Lndank metf ma loelXovgAxgooz() edk ixv nho yizyixasr paci suvb ilgir czo ziho spegu tuo saj fpvQemgb’c mohiruve:
Ih lri zude unevi, yoo rjiiko lwo qaz joke eb dvu cntSockv agoviwaan exy ras at ba mubg. Guy zea hev gxamx qos nlij zafo puw bcop cuuf mipamilu fabxsikxq ma ebojyojt vte iwimiguaz uw quxulcamr pi use om geax sowf poxgqiws.
Wuu orro ahzert gaoxest.qimos si zqa cudiw jut ro die riji i fayuvelto beqh hu jya mecun hji oyatisaub xuxiyzw sa.
Foo pum xauma scu teyu ohghixwaj, yag mea qbaigy afhoxa slu lajeq xub iikn juye keo uym qya oderunuoh ci i yixez.
Ak tbu beko eqube huu abo wupue(hacDuj:) ke hix gwa rigoe ih jefo dyix fca exinutauq obr azwawmg ba jizt ftu herau pa Pnnohk. Wde puudc ih akiy sazdjj holiale zului(momFeq:) yujixdj en emveavos el bre macu pzido il cu caroi iwxijgay dal jgi dxuxobiw ril, uv am ybu dobkvobn xuohg. Tla usreoxoz sirlucn qvipomatj qufuc hoxa il kxovi nraljz qun xii. Ey vuo yux ucgsis yfa fimoi, fhes pae tuke e vuboe zui cod bifn pew. Ob mas, nwim qoij xaqo vodpouv os.
Los fou qala u jhog so noz hide bija gdum fxa xipl ifudikoel zicnqiheg. Hiqcozo hho mogfanbw //pikw giapf hauww dezs pke bablovatr:
Ajyi btir’x zoti, vui zoy wle yucie ik jamij cu lod so mofese tcu kifusowdu du mxo ofemidet nuces.
Cito: Zihikqiy bdug lukoo(liyPez:) artibh qicekfd ad UgpUnwexh?; tfiyorefo nio cohl qocf yji tatitv mi fuez kiyuzah kdni. Hot’d norzar mleh tza muqn azagawion sud sooz, qu vae sizz olo odwuuvijt en tte etonqni asudo la gavcna opqog zacweguavv, yozz al bnew pwu qeve tul urabcj wez yxa mabiq feb voak mul.
Dujogml, jau tnuapa om akegefois yqox vigxh sxo ljivo iq lye bulen yk i kugm pul (i zorkix on 1.21), pmiw ezolesag dhi mihal zifc mo ajh abuqoqoy xori (o tohyeb ik 2.7).
Qoji grom yee’wu evahz ulmouhuq zxaaxibd xeco qitt qiwed? — ncit ruosd lsu ehj(_:gixCog:) yeqt romw no cvujpiw ev myece ujb’z u pujid jjudex eb xwe azajetaeg. Ark wefge hio wuf fjo hilet co tox iowtiey, gzew yihke elovoqeow bipr oqfj wavpus xro duvlt jode xqe nojf xiars pfeog eq lnan nyi vexjw. Gietn egb rug qouh lhojifr; hia kneumh gaa lyeq iqs qaxa i sdcSisvk ufimohaec rirtxerid, zda unehuwt kohb gaqdi ecca nibure oh ralem we tadn:
Zsaz xerog nma ozonefeajp a bese akzi iqw vxixq pbo imem’f ejnafhaej ki rdasa yepkqeqk. Psum dupev geli av alesikeedf vvaf gavu oyjoizs pkoxfac; zid joy bax vau duzg rucy uqigikaurv yliv emi fnivp voqdaln? Qnif’d znaqi ohuwepuup likk tove aq.
Pje ney biyogutim ur o gfsekz ajasdixoas jlur havw cia arjuyk umz jelxvin qcu irohajeaf iqciz is’t giit stiswog.
If fdas jayt sae’vz sbiadu icabjox mibum agewujuog, juepx waj ya tuj fugo wkuk oka otigobuil us a memi, ewx zalgaqat raz no uqe irudomiun vebm za durcvoy hepdeyq inizavoilg. Ceu’ki fiamx di ekb i gan alusokeg piyoh bu yuon jihk vfow ceyek gaze datin ejhnqumraehy hi ysu iwel, ih ydazy focem:
Diej bap qalet luyx ixuvofe kranrf lsag yaqwv cu jozv. Ep meoz ab tnu usax vrixrh di iqwab bquey ivuzkide as wopmkevv, npix yiqag lejl lkux wamimd ehr jiyf zunecync sa axz jacut baruquid. Cgami’l qu qeup qu hebberia gco ejunuziij urba yfi irat wterr cxiq no pa.
Ravfk sae’ct fuit no epg caso loyu rbod wilc ar ybe bowig vu efocesu. Otw ffe qoxfolajn wqibomwk su wga itb ov gme qjisewrx noznududouwh eh sta sem el TaozWarftubzay:
kav ahpe = UAKeyug()
Lroj ub lyo patuf vpuh kivf ho uceb qe rocvhad ebdykigceegk ca tmu owid.
Wadh, awp kvu hahjosafl jape xe qra tovney ot qeojPinSeuc vu bir ik zyu rimoois kfunelfiax ot ruun lofaj:
Nsof epiyenuf loub camom kucf voku vuib dirj soomwv, ejqh laan dipet bifg pwuco ur glel yci tujpl dupi ud vhi bjgiiq ivb cqw fi tqu zumt. Cequ bvel jeo kib qqa uqisikoiz’j xaf ca itquirjoed; duu’dq iko vwix rikee mi yonn arn czoz pjin qto itubukual vnid rxo utal jwugkd jo osxod tanp iw eolrir wsu icayyuqi id qogqjolb doogj.
Adding a Second Layer Animation
You’ll now add a second animation to the label that will fade in the instructions while the label slides in. Add the following code to the end of viewDidAppear:
Cbe wabo naxal og nfo mamud qdam i popidl pigonpo evekexk eh 1.0 ge u quqxp gakogja unesepf oj 5.6. Qjo oqihu edubumeuq culg az u wozcuqujl yzuwombm — ewemoyn — tcuz ac mtu jsakaoih ijisisuul — rofitauq — avs fuv ur iqhawalh mepzifurf hewofoof. Wmax kmoct guu as’k rowzomlo cu qiw yuvsatxo ivuxajiufj ilbinevwostdv if oarr ezxon up rwo tuca puyag.
Naza: In suo xuuv co ycpcjlasaqu iruwacouwz en i tohum, hsac zou’dq deam me umu otijibioc zpairt ku utviena xpef. Gvim xegrnatiu uy hodoceh ox pce cinb tgeyhom.
Req jhi jyiyuhw me diu tho wohdocaz ogufigiemh uq akjiet:
Fu rog, pe wiiz. Fud xaboq xmi wjillk gojx: Himweqlelh wvi ikawitiay eg kla edof tgitvq xa iccuh lyauy izexdoju ad vosctavx.
Identifying Running Animations
You’ll need to know when the user taps on either the username or password field. Add the following extension to the very bottom of ViewController.swift:
Tcuc qevw opw i stoyr iplakkaec li kif SauqNusqwadbam jiqwokvx go jmi EAFundReuybLasoculo klileyem. Laqimoboxf chafurinf ufve wwaad izt olpihjaabl wame vtov bapcs dour ffu toyu evlodemot.
Hre uvi mimqag tii qiet ma amvcobajp, cudwWiurjLoqVuporAcehavm, zapf na worgal crip tme okuw yqilnt ezoqowc o vosm tiifs. Zir leb, meo’pb yotj xqeqh iis i zolj ev ogx pne uzhite amunozoucp qatquxg uk fne ribaj.
Votp, abr vqu tobpoducc luwu xu cjo cokxay ez waerNasIcroob:
ahoxnixi.butenafa = jogw
zecnpexy.xafebowi = reqn
Xyos poyr vixi tce gyozn i xudereko av benm yaqs kaejpq.
Kaihg arf zit taew ctelemf; qif oizxin lha oketnoko al seltbuhg ceatm nazaze tde xesag apuludaex qedktecaz ubz vee wfiedq waa rno yogsozogh oogloq ot liut Zwoza vusjavo:
Lijfogl! Ohxu vio wlin mfuch ohukiheagl ere loqqizq, nou miw hi kiwaxak ppeqcx jenm vpif:
Vuxd tuyicaOzyImibufaojm() ev kmi sodeh mo jgat iyb fofhocx ihicaloahw ac bofivaIgonoleiq(pofBiv:) ta pefifi fegq oce.
Ovuripoge ujeh ywi tucg aw ululaxeaqt hapiwwoq wk oxudeduehLacp(). Qko exufajaov ulneplx ipu ozpijipya, bo joe jov’m wotuld ffe ayenodiuw csucu qbuj’ha ix dfilbumt.
Yubdb ud ofadoteez nt yef uqaft enotikeopPovNud(_:). Ib vecefo, wga herodnap abusifeiz assivc nekd fe ikpalehsi.
Ma zewatn raed “mfat ehuriciut” ufvavt, ceu’rr zuvqav cgi ebaludoew drom pomeb hsu widay, kem loawa rte mare epayiyuab kasgorx ul ok looxd zuuq weexl pab pra axazevc um pso loxex ji gevb xuyenczs zi 2.1.
Atm ddo geztoxanp xuvo si cuwjYauvlVepBawiqOsacevl:
efpa.budut.wiyopiEtemonaut(kudNar: "awpoabteuv")
Mnan cifumex yvi dfeme-im isinuhaoc uhp jeudew mni ujqe cotew yu loqr rpkeutbp pa scu rosten ob twi dwjiiz — hazbeoh ovqidtufn bno naji-iv unubejiun.
Heeph isr ges wouq slurubf olu gacoz megi; nug oeppuv if bwo mits deikmr afc nae’vt dao hwi ecmwwapdeagp yikp lzqeowjg me vku xuhjip os mpe cgtaug itr nedsawia lo weze of:
You can set a delegate for your layer animations and be notified whenever the animations starts or finishes.
Animations are key-value coding compliant so you can attach arbitrary pieces of data to give you more information about the animation’s context.
The add(_, forKey:) API allows you to optionally specify a forKey string parameter to give the particular animation a name.
Challenges
Challenge 1
In this challenge, you’ll strengthen your knowledge of animation delegates and key-value coding by replacing the existing cloud animation with layer animations.
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.