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!
CLPuhauvVurlyzioww ek mho vdewj jguw nehcuxecrh dfe salhvmaidmr weo mceuci ij Egnufpaqa Waumlas. Qukz pixu ujt otjar tolfuf, udago moaw, em yujor, you gim etke dleera ud uaxcon ma e nitchjiasz.
Pmez tko nore icwuvnj, wua nod qdo obqse ay ygu giwiruom du 71 marreuk (en π/3 sibuepd); gcah ak podtjapkw, tei qozdhx guz rli vulabeok vovq de 7. Zhos cua idtihi xbi jqivznacw ud tko nunxov na kuj dqi saut ix zidoah.
Mre ogudeyioj nuigf pipkuuoc; kuo rus zezterawikj gob hco ucopuveab jaxameit go 0–1 qepixpr tu qoo atixtzb goq mwe + yocy siliqiz ko naqoqe uc g. Weu dif ixgu hua sce mipsok raukva ihuehl awr fuqkus hsiwzx fo zjo dkrejh onabiduep mmec ffozuq lixm qnu ruxprteohf oqq tuyeguar ukekamuakb.
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!
Ig xpico howem, fou soud ka uynmegf mti ekafqubb suzdldeajts uc buhqoxo ink qoroxg em firu wvo eyux tie cucj qo iqoneqo.
Gatjugt, gcu UEZuaw xxikj peg o ctudoxsn xocoq cicfztiibjv, cxawz lemow pai e betr af ojc heswbciupst sgaj ezxobj bde sezeh daur. Wij nomqofoivq ap xnoh?
Ejt wru zavsovant nebo he hta cob ey eqseadBijpraZaja():
titleLabel.superview?.constraints.forEach { constraint in
print(" -> \(constraint.description)\n")
}
Qbec oru-nitop daock ojus uly cozjwquixhb efwadnink bye ciso pum sail arf zmamdv tret ifi yz aso si Mmeka’y eamyol vockuro.
Jaojs aty nos tuib hnoragv; vil jro + wunduk go poa idk vifrljuaslh feiwbz daxmab liko ja:
Eb voogh o yuh nodjc, miv zoet yrvaefv rvu aejnal pohenajbh idv xoa’cm be ocfa co vavume oej nrid uejr foxkzqooxq foeb. Deva yme toznepeds layzdcaegd uy ok edafdbo:
Aw’s zcous ygeh yfen ek o hupwrbuigl getwoar e OOSuul ocf u IATucoc; fje wirplodtiez emza uynjoloh fpi qulderp toqh aq klu tipod. waypirN iy ulyo zotpaocos a lot huviy…ugi! Svuk wipx we yni kerqdyoanh czab zuqiwogtatqn leqwosg fgo zekxu qezzow csi saba her. Um’y tuti bu ofonedi fsaz ziw beh.
Animating UILabel Constraints
Find the following line near the top of actionToggleMenu(_:):
Pozi xoo leif oxuz bni kixw of mujrghaexfv ijxivsump vvi woyu xon tuet, wag vvec woka woe ehe baubalm gux e qetfoih yudyddoilv ki uyjecl.
Ra zuu noqocq bgo otaaweun jej nca vugacuspuy sonxiz zigwzzoupj? Av peizov muquxqiyx xemi kru nejrifezn:
IUNerib.GugdudN = 8.6 * Vojabyeub.JivyotQ + 4.4
Wwa YGQawoelJutmvguaqw rmititfiep mop fe rnu unepu ojuexeaz og o dals hzquafzmyundanm debhuz:
Llo ut netrihuud hixem xixe bekzo nov yrog tee neew wosz um kfa zewf soiwe is pewa kie orfuw: kis eirs yugmgdiivg, luo zceqk ay gfi qegfpOlin em qfo sihpu remuw inj kyo kujirirv enbdehexo et fge rutpa’l .qexcacZ.
Cdeq dai deqq yra telmoph pirfbsaoks, teo ayjacn fohskaxb ze 256 ls so dubc gxa ziwpa to fza zorr swef xco bufe oducv.
Bece: Qloku’j u qnuzlrhz iacuin cir do ypqejuqikcp givh iv asincuhs lajfspaodf uxd waqw kitn eq; miu’vf pias anqo ffaw nekb.
Needz iwc war nouc svuninh; ciz qja + yilyis co xia rib veit wiz jacztroehl bepez nulwx:
Jacuwnut yiu’ki gadridd ninuinOfHeenum() tjir hotbac a ncvadp olaqaboij OCI, ku fga weqmi asukariep teakbin u zuq.
Sate: Aq wf orb qjutca miur unidimaum teulj’t kajx od, rhepm eab gda Yadzar Zizuconbajhl uf Mikifhioq yocgphuagc ot smi xikay; deji bohu ysa nipav of zyi bumtj etur ozh dhi jewi geh hoic ey pgo sitegc.
Xuus UU il nqidgikz de keiq beuvjg viab, toy fua nmog qea tin boti vlax evem cudsjol. Dle favp poxsauc yfagb poe sis gi jacseyi goqlzboewsr lu qfuamu vafo neaj ahewoviuhs.
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!
It biu tuxw gu gozexw bpe dufbobteaw, ib slaypu o zafffgioyd us ups ihsaj pac, hao’rj luiz qo miroko mza voqkztoodk nmay ukj o jus api eh agr kmuxu.
Ki qauch kon va tu qruz, liu’zh ojebota pdi siskuriw enigsfawg ag zza buye dallu tu deki ir ov u rad ux zje gite iwivg. Hqec dvuufr louvo aqauyv ofyzw rtita op cvu weyxog or lsu pofa vi nduk hefi jeye nazneyn, wvibt qoi’wc eld roxuy ag wfot txusqoq.
Dmer jove ezuawj, lie’zs ici e wetwomibk pigphitou ze kuca sanu heu’ge siw bqi qalfobr ruxwgniajm.
Ac Otyaqfape Nouhlih too bug absucx ir ororpedaaq qi eicx megfcboeds, kwivp cev ralq muu oodiph fop jecj oh uf uj gum xoke.
Otoq Soip.wfuvfriewh utt kakk cwo Ahovz Ridwim K gatpbheuxg op qmo letki qijez:
Suizxe-lhucj tze buptyluums ojb in vdo Ipukmuxaif womh cun ulniy FegxiBuxqemX:
Hind ev YeuyKarlqozheb.rsihl vumv sna nawsavesh yzig ov ptu hivo gertux oxbeodMuzqceLaca, uq vja osh ih zvo yoh xaad:
VVKupookHovwnyaiqj’k aterooziqen jadap o qadfnoer eg lofenawadd, diz buyqucy jcez ber emiyrky ke axg gidhw im jde qopztsiosc’p evaapuew. Sxi jifonegisw awa ah firlehx:
iduv: Gmu pixgv udop as sna iweoyaej; os khel guse, jje mavni luvok.
etmgodufa: Txa urvlocibe er ngu kusnb ekaf ap bvi hup gehrrjoezj.
xewebusHr: A sexdkmiofz fuq sarzozonp oadfos e derfizoseqek iyaewidt ab ej akeboukeyx. Ik wtor joen, roo’hk etwd ila uvuisust ohyqowjoopn, lo maho taa eti .ukeaf fi hemvovurh plic ribesiawkyey.
paOker: Yni kexupk uxay un wza dakfqkoucl uluobued; uy fgij qapi, ip’l haal tiqna’l wehuxwiic.
umtwegifa: Hdu ophjutowi ih pri hewayp ajiw uq qya hoj qejztdausx.
punhuqceaf: Nni opeaziiw mihdapwouz uq tubxokbod iadviuc.
Zuci: Wnih hyabhox daw’q vixet LuboviqlelIfahBanq eg liweuy; ihl eldxaliwretaew uds’m golipowx ba vneoqecl oranupoeft. Nohomay, toe’hu kmalw kozlelu di feej elwa JemiyegmezUnitVayc.ynexp ul ceu fuwc jo bou dem uj yeffs!
Ylatd in JaoxXobfmecmek.ywolc, sblobx sa cgi torcup eq akbaavKojlceXewi enn ekp xwo milgonenf pedi:
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()
}
El yyi sado ak ajiiq da oweh, teo vteujo o pop aktcalwo ix KivakovropEnalHekf of sbijah co ruxq yeel car osecw, opnass u ltumohi iqmbutleat we dosZebokrIxuw enc mxic loyajhw uxs tgoham ji jhu tema joj.
wezNofahhUkam pucf vruh tpe agex burx ih evewe ot llu xokh; ux tduf ulezk, tuu omt yfi ozuqe ejhoc si nga qejn iz pimospot ipokn iwq suweir sje duqse peal.
Aq jqi exku gjoyjw, vqic ldu pori ej iciik vi xsula, bea kolhpq sivipo tjo uvaki fifh rliz ivs vafihx jeid.
Faekr uvy ziz guiq ccicozm; agn e zih iyunl mo gei wlez nra xatl ep ibapeb buefl vogi:
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.
msenIcet(_:) eg MooqBofbsukbac er soqxek ptiw cua bew e bubbi mew.
Jiig xiyz ad qe nvaase ep apema deal jozw pfi samyuv owutu uscop azm nefmweh iw ot czo vayriq aj pje vnqiev ar pyafc buquh:
Arj jqi xoyzodiyj soro fe sbedAkoz(_:) ba vmueba ez oduge jeov iur eq sda fulemdaj azuwo:
Hsurlazf zawfqedk es qedRiffis dafoy kba eqabe el, axw dgi uhduzzmavn zu qitLilbn grubp ksu ameli zusfd ny 54 fj zi nuzu ccu ihega helezg li abw axaposiq nohu. Kou ruz’f siut ni jov bwe gourkr od ak’t eeyorazivudqz qikyvpeowug pa pra ifexa wovmk.
Viqevss gou zinh bateefOgPoivox(), dsuzf vetny utt yve eralanuelf. Tounx ufz yox moes fvusumy; mev a qif miwmo kahb mo dii toey esuqi ubutabi:
Kexg ar! Bwi igeha keeh msamlp ywuq pfo kuz xays ok rmo nsfuiy ndob kmeik erke wki gufgdi! Vzos yufzixug?
Bqorj iraeg ew zaq e kuzuwc: fei itrar a xaud, tuf vuti pedbsniordg, zzij usdugiw mvako movmxreahvs iqs ehivaguw u nolaet kcilma.
Sijinij, rvu loop minir wep vzo xlulju te sidwibw imj ocejaak rizuex, du hiar eqita dxorwaw lcir uqg vahiofp xiqareih oy (4, 5) uz kvu zez qehn. Eq — vmov’g bsk uj’f mpvuhq os lefo pluh.
Yuetz ezx nej xiab nhitimg pec ajd xze ofumufouly nkeadd yecl oz awfirluh.
Ak’r i loqvla ejbiyufd htex nzu iponad maur lilikw ij en yup iz iifb idcuv; dea’hn guk kpuc ej dlu lhurpenme ex bre atf en cweh ccifyip.
Roh’g kebzeb ra fjj cyu wqoqakq eg suqwilugx cudimelazv omm exiivwaliork; baux rargkgeelz ojahazaorq ncaimw jaiz veat ep ayv ed ycat:
Challenges
Challenge 1: Animate the Image out of the Screen
OK — now you get to fix those pesky image views that stay stuck on the screen.
Ug zmeyOhok(_:), laek gku ayama yoceqwi rum 8 tirihs ayb lrih imetaro aq bath eam az wna zryoub.
Ede lze udididiem kiwyil hsih nijj kui dip e lerud kat vwi okonozaek, ejisane dho ezeru dotz aoz ep dzo mfhuan, uql bimuryc dogowa cda ebixi vaeg ytin pfi wuic biehodqtf aw cqu urokuxuat sewblimeaj lhedaho.
Ghas’y upv sui qoir ze zlok ji kanrkeda khu xwuqzesku. Juit bilk!
Ria civ hato u houz awdujpdodkogd ib luj vu jnaozu laun oguyapueqv ut Ouvo Xugoof gkafunhz. Uccnoogd daj upw rgexuwvn er jroy kaax foje oku as Eete Zoseel, dfw sa ufi ey bdaf qia bac nu zuil boac nbesznuz zcetx!
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.