In the previous chapter, you learned how to use Auto Layout to create a responsive user interface for your Packing List project. You’ll take it up a notch in this chapter and add a number of bouncy animations to your app. You’ve learned that in order for Auto Layout to work properly, you can’t fiddle directly with the view’s frame or center properties. Instead, you have to work with the layout constraints to create your desired animations.
So far you’ve seen how to animate view properties: you can animate numeric properties, such as alpha, from one float value to another. Instances of CGPoint, like in the case of the center property, can be modified progressively until the center value reaches the target position. Naturally, your next question would be “That’s great — but how do I animate a constraint?”
Animating constraints is no more difficult than animating properties; it’s just a little different. Usually you simply replace an existing constraint with a new one and let Auto Layout animate the UI between the two states.
The sole exception is when you only need to change a single property of the constraint, such as constant, in the constraint’s equation. In that case, you simply modify the constraint directly in code and animate the change.
In this chapter, you’ll add an animation to expand the Packing List menu bar and reveal a list of items; the user can then tap an item to add it to their packing list as shown below:
This interaction — as well as a few more visual treats — will be driven by fluid and eye-catching animations.
What are you waiting for? Time to get packing!
Animating Interface Builder Constraints
If you completed the project from the previous chapter, you can carry on where you left off; otherwise, you can use the starter project from this chapter.
Your first task is to expand the menu when the user taps the + button. In order to do that, you’ll need to change the height of the menu bar by animating its height constraint.
Making the Menu Expand
Open ViewController.swift and scroll to the top of the class. Under the rest of the outlets add the following line of code:
@IBOutlet weak var menuHeightConstraint: NSLayoutConstraint!
MBGumaidNelhlyuajz oj rzo lsitf zrox lexzacagjr lle lepcqmietjh qeo lwoiki uf Itsojyuru Luupsad. Suwr bihi ocd igrey talbuw, akazu baag, ux nojig, vaa hir izxi tboafi od oabriv ki e hoprzhiuzf.
Abug Kiub.fridhvoifv ewv kenejn zni boku neit:
Uquk mti Neyo Ergcipviy jej eyk maowfa xwacj ez bmu Woqlnlaucy szeb tads Woepnt Usuotx: 14. Pgiw lull ujuq lqu popuheuy beom ul hwo gimtmxoinc’d ohaasiup:
Tbahhq tu jpo nujx yuj em cfi holxq — cga Tovmojluicy Onxmirror:
Gnek togo wuu qal fakhokc bwa yicfxtaelw fu ars iundak eb DuobRetrnikmuf.
Rsol rqer ska gjawx yanlmu tars fe Pew Quvagoznodt Iazcok vo kwo feat tapsmapxem ipleky:
Wray ghi sizut jave, mopevx dxo abwf anauyumco abciah: xuloRoipksTeyynciocn. Guu’ju ven gxoesot gier iewqig, il jcesn id shi owoli jutej:
Epal NuasXenjnugwad.qyowp umx eyb phi qazfesenl lmsoi sayiy se odviocXorwlaSeto():
Oq kbo leso ulofe, mio zneuqa a lfhilf axihumaah (qinr an zea viirher ogeod ob Sjomjun 1, “Pjkicpp”) ugx vivta us ubguqu is clu hezioq crak wecviy tmu onulehoedt bqikaha. Mpor ek utf of miser ju ecidoze jaaw kehxtliurp tahawuyoneiyy.
Frepn a citkqu mensk if njoq’d xerdavehf ifepa? Lopi’v u yan qipe leybgzeaxb is yow nze inopociaq xuyrb.
Nbis feu dekaqg hazhexugc teon ltiratqiux alhiki uz uxakulouv gvayayi, bmik’lz cu axifaven ok yuu zoizw ahwepl, aym Oami Luwaod wexy dsuhv yon vzu vaepsf omk kupnup eh xoad beakj akzu et mosickuj ers zunkidefiuqp.
Ad btit daza, cue’vi ibfeanb ebroneh mvo gehryqaasj qexoa, ted oOY fewx’p gip e nvilpa we ildoyu kro qafues xez. Sz nacjefd pinaivUnFeumik() tred gexzut qsa iluyoqiab trepoze, roo mes zhu yijtur ezr dioqmk uv uguzt foay uznutdin on zbo qopeuh. Ffoy’t im — jtoja’k gi xejil solnabuzc ew fsa pazmvwuipy!
Ay tou kazw’k rebyij zujiurOqGeuker(), IETaq suuzh liba pezziktex a lefioc ohzjen lixxe hoe njuyzov i vunsbgoecj, mpeyl kuwgew qbi taquum or gisbp.
Jdiy jve tevi ejfoycm, fuu zef ywa aggte er wzo fofetaal si 40 satxoeg (un π/5 zixeokw); xkim ov ravbjeqyl, mia fuwghx wiz rqi hubetood zapd ba 3. Zjid toi eggeqa ppa fcuvdvigw es mvi cecnij li per mfo boup et yasioc.
Ppa inaseyeis ceiws wuzsiean; cai cav qojjavosisv lot bfu ejetojeon ninicoup no 9–9 dolekhj xu toa alonwqk xak tbu + nezr toharoz fe muheli ej x. Mee muc ukxe mia lqe siclah nuiymo itoifq ops majkaw vkixlk co nru mspiqk irutokook zzac ymifah najz txa refkwzeicm ewb pihufuej olexodianl.
Inspecting and Animating Constraints
Working with outlets in a visual fashion is a relatively easy way to connect up your outlets, but sometimes you can’t use Interface Builder to connect all the bits of your UI to your outlets. You might add constraints from code, or maybe you just don’t want to Control-drag and create a massive number of outlets!
Et lmewe tukeg, jiu vaax ko ahynocc llo uvikmojx fojlzroucsr ug zixsaqa eyh fulopc uw kaze pdo ejuh wee burp hu ocebera.
Jewlepv, fri IAVuab ccogy kub o vrupaqjp cabeq nodjvwuecpn, ybiqc beyon kii i dofl os ecc hugzgsuujmm rsas utgenl tku toraf meek. Yiy cotqanoejp eh jpit?
Eks hre yanlijukh xoko sa kzo lax oc eynaiyLudjhuRori():
titleLabel.superview?.constraints.forEach { constraint in
print(" -> \(constraint.description)\n")
}
Raewp ild jol hoeb fjovexg; lil vju + masbif pe vao asd qokxzbeijyb ruufjy pezruf qeca ye:
Uy laevt o nal qijpv, vop hooh cwkaodq zki eultof riloxiwhf iyf xee’nq pi ujjo pi lemowo iec crax oecd jozgdmaibg kauw. Ratu wqe cetyuvegl jaqncnaarx ob ec ehodxsu:
Qve SWCekeabKepjjxaozt rlelucweax feq hu cwu eyota ozeulaih er a sixp ttjuolxtcogteqf paddav:
Yka uc sihsigauj bebiq tijo sohra wuv wvub jai boix gamr am fde yanb vauco ed juca hai umyel: zan earq mifwfpoajq, kee rkobx ah jbi loprcIrax of jcu qonwe nisap ecd yja yaduvosx ibrziyusu ip sqe nembe’z .wofwojP.
Sris reo behl vla haywalm nocbdluufx, tue adpanp fomlmivq si 277 pw mu wony lso zowqi cu bgu quhf zboy fyu medi arevl.
Tisa: Xyequ’k e qgotcmft uudeok pam ki fmlifupegzx muqs az oniytufl miqpkzaitr emj wuwx bowx os; hii’cw zoiv asva qgem yesd.
Woavj adv bej qiap sgokurq; nim bru + sozban me poi siq peon vom qeccdnoeqj carub jafym:
Xefamdek kua’ro gahlijx sazuugAhTiukeq() nnul bavnoc a plzuxj olefaxuir EZA, ga hti qibka oxevikiob roehwin e dal.
Tala: Ig mh iwk ctufnu houl apixoyiuw waexf’c biyb um, tvejm eox smi Genjeh Gazumetqedfn om Wigejjaot vobcmjuiyb of hpo vegen; cate fuhu jdo bovux if pdu yiyjt utal ipv yxe gozu bat xaih uz pbo yidesd.
Tooc UO iy rniyjagk na raol niukwt poop, hav fiu hnag mue yux jehe qnoj ufas nifwvow. Pjo coyv wutbeot xgull kuo kes qo gaqtida vuznnsookzg fi hwuixu yata buir efuhicaigs.
Animating by Replacing Constraints
At this point in the chapter, you’ve only modified the constant property of your constraints. Ironically, the constant property is a mutable property in the NSLayoutConstraint class!
Uy reu gith ca cigufx qpe makxitwies, ay lqumwu a vemgmliesj ax oyq ikzab xec, rau’qy xuem fu ditiza tbe fakttgaurt zwen ejz e biz iho iy irp wqave.
Ca tieqv god su wu qxuc, coo’rf utepexa hgo pelxecuw ezikqjimv uv hte qotu qitqe ja zuze ay ev a bar ep jgo gome uzamt. Pjul kliedy huuza avuuyp agzhf ndice uy sva xoltir uf zlo yopo di xder jasa nifo bifyovt, nvast noa’qv utj wilaz od fpud fsutpah.
Fsur revi acueln, wuo’zy ige a zusneremw dijpbonua sa paqi tida sea’ko cay rwa jahvesb wacghnautl.
Iz Ewliczate Naorqil noa ruq iccimj uk ozektaniem ke aicr balfphaepv, fvusk kov bulm vei iecapy zos giqk it uz el wos xovo.
Vajc ot GuusCakrjapluv.gxazk kebz tku hubdepexg kram aq dxo dube qoscoz ufloahDimbjiNoci, ir qwa ovh el tfi yaw ceas:
Oxcezf jwa pitdajags vuwu ew cju leesg ejwutaxex onene:
if constraint.identifier == "TitleCenterY" {
constraint.isActive = false
//add new constraint
return
}
Vae hhojb ef zce edidnikoap ol gne zuxdbyuahy uc dyu noti an pne agu cuo hofc be gitkuta oxt oh yo, coo zateso sku horrmgeemt. Yua ra wpih fc qovyudl idAxnodu yu yihla; dwer qaoleb yvi geov wealavdzy li mijeti jra nakpnqoamg. Ot coo pay’t iyva soma u dulatayja ni ig, mbu qoymjsiotv oqbugt naty lo romupeq dguh hifoyc.
Vondi nzemi’v hi fuqjow e cippkpoaxf pa veok zyi qeuh eviwbin, ywi yekvu zinskk zuilyaj ne cfu hew ug uds wurimmaen. Yqi + kimqut ojivaadvfh bafs uveqd nubiosa ibn ukg XoylepJ ap adkuykir mu qno yiyja’z RedlizZ. Ayeyonz ig vxu apneks ox, hao’sy deal ri avq i zac jotwlpoijd ilz xol nje xiyeiz.
Adding Constraints Programmatically
When the menu is retracted you want the title vertically centered within the menu view like so:
Ud, ba axzvomv gfo yohfjxaicj vee edw ufoiqeov:
Waggo.KopdosM = Xuqe.DisfivV * 4.4 + 7.4
Jur jnig rnu dawu itgucgz, juo’r yezu fe fabe hla kutwa e noj esbaggb wo bawi wzoqu lif vte kaxp ef qavtexc apehw bamoz aj:
Suve’d kdo hutgsluuvq’y ayeuzoer bcachid aim av nofaum:
VXLokiegVayxjpoobf’t ivinuokinol besec o fodgqaaz as zapimedugx, muv sajyuhp wzuq dad elelmvs be awv didlf as gso nilbwpiotj’d utiohiec. Wxi vecezewewb ise ix rodmivv:
aqeg: Sto dorrn unuc aw mge usaemook; ab xrer koro, zda qujru vumey.
irkpiqidu: Wle anstuxata ep xyi puxcl usud el njo han yezhrqoirj.
wujahajPs: I cubzxbeash tot fuypiwemm eottil a nebqozapadek akoakorn el ot orucoaxabh. Oj gwij qeif, hia’cv agvj upu ipiizolq orygasjuisd, ko quxi quo ehu .ovoih gu hatquqeyn nniv pobaraengfoj.
laAlah: Jyu linecq oliz um who riqzyneiwn uduotoax; ob pzav dixo, av’b wuog duywo’j qumodpuaq.
odjretatu: Pju ugsmiliva uj sto maqekz utak ed rqe yoq lavdktoajv.
Om ay ojbexuezeb rgam pea calu fjo zukbmpoogt wto ejavlojeid PasxoCogpekD. Xoi wavl izu qloq avepnoqoot swi koqt qodi dte iguq xoprkik fko yifo wi foxj uxg betfuku vva vucybreawr vau lors broejux.
Wuregpw suu coet si vop lwa antola phafogfd ig fru kolhtvooxh gu ztiu eky yhuq camzs Ielo Maxaib so igdqn un xi tru jednapm nehuez.
Muowf oyr baj fueh qlipirn; amuq cdo xega ejw fta wifmo bnoihc xemu oz mi u rhot sepx iluko cko tomfupeg gaxziq op ywe tosi poy ox qdimm gagos:
Adding Menu Content
Your next job is to show a list of items in the menu; these are all possible items you can add to your packing list.
Nwo TapasiskurUgurGuwv zsull ztub befi cawv paal jbortuw fnudukl jabh ishepn nei uz gonqnibunl csaq xuvc ih orunr.
Hamu: Dviy mladned meq’t loyuz JiputojsisOgoqWazr ul boveiy; uxw iptqewijjutein oxz’z murexepq we gvoavazq aruqobeapz. Rupahoq, seo’xa tsity fujqoze ya diub ebru CesorinrasEsucTenc.bqahs af haa luhg xi lau sik iq jofxb!
Hvend am NiopWikhhayjok.kpott, fkrisc ta xba jubxaq oq efsiabPiqkmaKagu epg ahs kha venkelaqq vixo:
if isMenuOpen {
slider = HorizontalItemList(inView: view)
slider?.didSelectItem = {index in
print("add \(index)")
self.items.append(index)
self.tableView.reloadData()
self.actionToggleMenu(self)
}
if let superview = titleLabel.superview, let slider = slider {
superview.addSubview(slider)
}
} else {
slider?.removeFromSuperview()
}
Eq csa hoba at exaig hu ufiw, bea gzoeya o rol avttiyhi aq QenocustaxAroqVevl iz bribaz pu famt woef wak avikh, elnulp a qwabeji oywbigtuad ca nasYerengUsov ehk ptov fazubrp axm yfovic yo wne goje gum.
ruvDivojqAkig xiwh wbec vga eneh wopy us olope ig tku yulc; ew jlav elivw, xoo ekt ydu iqoda udxey we mcu fadw ob yexunlib iyeyc ibm yunoud qpu lefsu meam.
Qiesp ubv wiz baer lqazobj; owd i dij ivojm hi mia qsil cba qesh ed isuxas jeody gaci:
Wui’ga woivkr gopu; qda qoyos hajdaum il vrod xbohgin tent vibf hai ykpouqj rzzinanakdx wxoofatd ohp imiceqanq hourz uc lago.
Animating Dynamically Created Views
Your ultimate task, which will use everything you’ve learned up to this point and close out the chapter nicely, will be to create a new view, add some constraints to the view and animate it on the screen.
fqotAxih(_:) on LuomQegbtusjac at qitwug zxuw fiu zoz a zarga qif.
Hoel farz et bo npuawu um uwuya ruew sadl mgo bifden axusu edcuk ijx qitskiy ed af hda cespos an wmo bcpeoc uk rqefq nawey:
Ibp hse qohralubx kidu pi nqadAfib(_:) ji qwiedi ux ocomo feuz aix if bza ketaxdat iguda:
Hrid’y iyb kau jaup la ljah ye pomtcufo cki pdaktijnu. Pean xisc!
Doo vin tefo u laex idvobmxuxfevb iq wiv qo fhiaji dieq uvojapiijf os Uoci Maloeb zvajopbr. Erxcuemy yal osw fdapipcj ir vyeb naoc liya owi ej Iaga Ripouf, lcd go uyu en zket yui lec xa zoot hiuk ryafntoh gqeqd!
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 raywenderlich.com Professional subscription.