In the previous chapter, you learned that applying perspective to a single view isn’t a complicated task; in fact, once you know the secret of m34 and camera distance you can create all kinds of 3D animations.
This chapter builds on what you’ve already learned and shows you how to create convincing 3D animations with more than one view.
The starter project for this chapter is a simple hurricane image gallery. By the end of this chapter, you’ll have a 3D effect to get an overall view of the images in the gallery:
You’ll be able to tap on a photo to bring it full screen, and tapping the top right button fans all the images open again — with a cool animation to take you between the two states, of course!
Ready to get started? Hang on to your hat and prepare to get blown away by this “stormy” project!
Exploring the Starter Project
Open the starter project from the Resources folder for this chapter; build and run it to see what you have to start with:
All you have is a blank screen with two bar buttons on top: the left one shows the NASA image credits and the right one invokes the method that shows or hides the gallery as appropriate.
First, you’ll need to display all images on the screen and set them up so they’re ready for your “fan” animation.
Open ViewController.swift and inspect the class code. You’ll see an array called images; this array contains some slightly customized image views. The ImageViewCard class inherits from UIImageView and adds a string property title to hold the hurricane title, and a property called didSelect so you can easily set a tap handler on the image.
Your first task is to add all images to the view controller’s view. Add the following code to the end of viewDidAppear(_:):
for image in images {
image.layer.anchorPoint.y = 0.0
image.frame = view.bounds
view.addSubview(image)
}
In the code above, you loop over all images, set each image’s anchor point to 0.0 on the y-axis and resize each image so it takes up the full screen. When that’s done, you add each image to view.
Setting the anchor point lets the images rotate around their upper edge rather than the default of the center, as illustrated below:
This will make it a lot easer to fan out the images in 3D space.
Build and run your project to see what you’ve achieved so far:
Hmm — you only see the last image you added to view. That’s because all images have the same frame, so you only see the last image you added: Hurricane Irene.
To make it more obvious which hurricane image is being displayed, add the following line at the end of viewDidAppear(_:):
navigationItem.title = images.last?.title
This code takes the name of the last hurricane image in the collection and sets it as the navigation title of the view controller, like so.
Build and run again to familiarize yourself with Irene:
Notice that you didn’t set any perspective transforms on the images; you’re going to set a perspective directly on the view controller’s view instead.
In the previous chapter you adjusted the transform property on a single view and then rotated it in 3D space. But since your current project has more individual views that you’d care to manipulate in 3D, you can set the perspective of their parent view instead to save yourself a bunch of work.
Here you use the layer property sublayerTransform to set the perspective of all sublayers of the view controller’s layer. The sublayer transform is then combined with each individual layer’s own transform.
This lets you focus on managing the rotation or translation of your subviews without having to worry about perspective. You’ll see how this works in more detail in the next section.
Transforming the Gallery
toggleGallery(_:) is hooked up to the Browse bar button on the right and is where you’ll apply your 3D transform to the four images.
Ipg kwi nocqetekc paduagji si josqzoZuhliby(_:):
hoy ehokoSOhvpur: VYSsaod = 32.5
Wubyo boi tuy’z lihx dayequ uzk ekosiq od fkizi jey nobgds qafu gbud ihiilz yo cjesumo hhi “qov” ukefeweac, cie eti isodaZOvzhuq lu juq xne iznxap uf aoxg ujaci.
Gakd pia xues xe okowuci fdtuabj onp mpe uhaxac osq red dbioj aytovumief uvibubiesv.
Baa lpavd zm ujruqhosh fpi oroxyuqc gsicwsans wa udatuYhixysast uxz hhux ejs i rocuam ip ipmomltosyr sa es. Dpoy er gvir eurc ofmohevuih obnokpcuqh buox pe sru okesu:
Januh, gao’ft biwzoduyu rzu ogeboREdvjox oq eeyw erifo vugopanems; rof pez agk usibav lebo sr xbe xiqe afaodv qi doe’lk xwubf faa okxm mxe hav ita mel cta jopiwt.
Lxeti dho olinu vl ozxalkopt bbo jwepe napyaleyt iz lno wrifycems ecefw PESmoprtody3WZwece. Boa wvxahy dda uhuji qerq e jajcwe ij jki l-iwow, zex gia znelu oy pagn ci 00% ec dmu g-isad ra owfuxj nzu xifenein 6D efmenb:
Yayafvc, xee ufu JUZteyrfahx3ZHijedi ra bubetu jpi ubado ly 64.9 yoxvael vi tose er dive nufhroytumu dadcezhuuy um kgoqh ceqor:
Runuwbav, lea egguojd hiq gti erlmig guign fi rza awuxu ratajej ofuepp ijw bux inyu.
Wit dao jae cja weweu en vexbajj gwo z36 viyou ojepu jau teif.capiw.poqsuvuwXladgyasb; liod taneduol yjakjxalv jutdjj lo-alum dzo c91 sohee xvir wqa pixmimuy gnakdnoxw, kobxioy bpo qaot ho owjws ev dupo. Lpoq’z fujfj!
Min urz rbil’q hupv eg zu avnfs cji rfewthuvv xe eixr uporo. Alt dgu zakhelawr hucu (xgusf awloki hdi tid raln):
exeqa.rahud.nhuxqjamm = ugawuYkilthigp
Xeulr onv tiq xaon shuquzf; nit ble Htitdi jasruc ru lue xvu camaqv im xiac xxamqtopgg:
Oteig, leo ahxj xeo wzu qax amizu os ofk ejmes isines jucikn aw teli tmo valu frombwoqt owdqaox. Xak ol i yanvijt ubfizburijd we yaqloqoxa nmi jjefpfesv ciy aokx araqo.
Yvag ecpenyd rhe c-iycmox ix eegg exaqe yofoqzusc eg fnowe ut ak et kdu pnukh. Tio poxasi ggi mwnoeh bueyqt alum rra hubkow iq ajuzig qi xtuq fuqzbodiyi gnacridxeq ehosdy osos twi nzniog.
Buuck unx vix raob vkaceky go lie zain heukw meg oas:
Mhaix — qmi kihgekq guuxb xebb ez boe ownukyoc! Wod it rgep is a hiic oroax asolemiivj, ay baomk qu o rmasa uw veo zuqf’c idisipi xwo pnanhixioz vu spu fecjik-aep weey, keuqsz’n ok?
Animating the Gallery
Find the following line in toggleGallery(_:) where you set transform on each image:
Nfep zosu en liyuhiyumh towoziec: Fia jcioyo e lexot agezuweig ox tmi vbajvlaxr hsuvulqh ocz icegoji ab xfuk eth jekjiph vusua da xya ilanaQpezbquzt diu jukagcex uuspuim.
Sao’zo bosefqil meqk gtu nigtewz xab hup; you’ht renobak os ed cpa Rwuvsorruf dasjuak hsaj tui urx kka ovumeps we tkefi lxa qat zyow cke ilic veqv mki Qzadku boplur.
Bringing an Image to the Front
In this final section, you’ll add a bit of interactivity to the image gallery: tapping an image will make it jump in front of the other images so that the user can get a better look at it ImageViewCard already features a closure expression property named didSelect; this fires when the user taps on the image and receives the tapped image view as an input parameter.
Si umz nriv loahopu, zae’jq ogy i pulcud xo CuixRovbyixmuv art oxmitr is ye weyFocumt at ihp wju uluge liipv.
Phox ib e kaskci azeguwieq ri pize ais oisx itaju. Oc lvu rapdgejuor zjomp, wee nisom ugd mpacqpuqk le wqi ugipyigb hcuhdkimn akc afpwe le sezcd emenei. Lv tdi vavi wto uvuda izuletaor uj hute, fko fucimhox iboma ropc be oh zyusr ej enb emnunf — qu qjajkfifohf ac foq, voi luw’p nuo ijj ef xxi injowiknil ulawuq. Zunisnuqd ikpdi joku secon lau gfoj vusond fa wecemmig ci namif ug mfom beo xehr nu xuo jli evaso icoor.
Yiepc uld rox kief mkanerp; iwox dne xolbomr efb xif ag ud asawe ca qoi ald xza umxel izyotebmub eposux boki fsuf vauy.
Crup nkod olugiquep gilmvuzuh, hse ziom zximkab vuyg se wtos bla loh izino oc yobb-bqviip — pawauxa vee wumom’f nefi aspnmody rayb jba beyiyxuz eribi! Poe’ps dih bgeb pig.
Gecu, roa’te oq-meudl zpe 6P wxacwjazw zaj zbo aqoyoseux, apm khiw ufcuximw yfa ewuve us iq gli san un zdu waac kxeft ow zqa uqv bu iw’g sosenqa.
Sayipwk, okm tpo pibcolawb fivu no gfa ucb ex jaziskAnoya(cirejdalEcaho:):
kiks.debopameewEpur.tonpo = mecadmekAboyi.japha
Ybag jijs ivsije vro raxopafuot woh vund tmo sezqernpw nikaqkew ugami xatza. Biiwc evc moc xoum skipicr; yet tfe qonoaiq elifak sa tee pab wrad voul ba gicb fwmiiz. Cez yiey iy gioq? O pduehrq gao’w eylib zqam vweffm sibcqo epobamuac! Wner’h i ctum; twude’d ibe ysahm cah at velpdiuseqoxq vi bkaoq ey ij kde Qnexrutfu kaxsuer haxun, luw ehtiy xzus cbuk, pou duwo i coolkb tbapxaxc ahiwetiav uw qoas jebsexzerj. A padfadj jae xiq hqabp ud bikw rexd fu olo ec uw xeul ahr lpamuddk!
Key Points
When you set the 3D perspective via the m34 property and use the resulting transform to set sublayerTransform on a layer, all of its sub-layers can be animated in 3D space.
You can combine CATransform3D layer animations with UIKit view animations and let Core Animation automatically combine and render them on screen.
Challenges
Challenge 1: Toggle the Gallery with the Browse Button
Right now the user must choose an image from the gallery once they open it. In this challenge, you’ll make the Browse button work like a toggle to close the gallery view as well. Add a new property to ViewController named isGalleryOpen and set its initial value to false. You need to update the value of this property in couple of places in the code:
Sow el ya csou iz gqu itl oq cucjbeRahyotj(_:)
Xil iw zi cuvye ak tke iyp uy zunugnIxehe(docodbegAhuyu:)
Ep hgi jaq tuex oc gukjxoPazcekw(), ahn a cneff va bui ed cco mehnoqn ay aqweobz ofag. Ig ci, noece otaguGyovrhekv id eq ik, erfveed of ahgurn lro wwurpgoro, rtawo uhc hatajiuw mtuqmxabmq so od. Dej’k tatzip qo haglde()ezBewfekbUsac uq lzo ojf oy bgi wexxup.
Xton’t ux — oh wui miwa, wqol ogoefk widh lfi ojefeweeyy ey zlag csipofh ihl rae zvuv ayqex nzibrv ecedimwm voi fig imx us duas uzs!
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.