Presenting view controllers is the common way to “move” the user focus modally from one contained piece of UI to another. When the user has finished making use of the presented UI they will choose to save their work, cancel the pending changes, or otherwise actively dismiss the UI. Whether you’re presenting the camera view controller, the address book, or one of your own custom-designed modal screens, you call the same UIKit method every time: present(_:animated:completion:). This method “gives up” the current screen to another view controller. The default presentation animation simply slides the new view up to cover the current one.
The illustration below shows a “New Contact” view controller sliding up over the list of contacts:
In this chapter, you’ll create your own custom presentation controller animations to replace the default one and liven up this chapter’s project.
Looking Through the Starter Project
Open the starter project for this chapter, an app called Beginner Cook. Select Main.storyboard to begin the tour:
The first view controller (ViewController) contains the app’s title and main description as well as a scroll view at the bottom, which shows the list of available herbs.
The main view controller presents HerbDetailsViewController whenever the user taps one of the images in the list; this view controller sports a background, a title, a description and some buttons to credit the image owner.
There’s already enough code in ViewController.swift and HerbDetailsViewController.swift to support the basic application.
Build and run the project to see how the app looks and feels:
Tap on one of the herb images, and the details screen comes up via the standard vertical cover transition. That might be OK for your garden-variety app, but your herbs deserve better!
Your job is to add some custom presentation controller animations to your app to make it blossom! You’ll replace the current stock animation with one that expands the tapped herb image to a full-screen view like so:
Roll up your sleeves, put your developer apron on and get ready for the inner workings of custom presentation controllers!
Behind the Scenes of Custom Transitions
UIKit lets you customize your view controller’s presentation via the delegate pattern; you simply make your main view controller (or another class you create specifically for that purpose) adopt UIViewControllerTransitioningDelegate.
Ejibs wasu tio flixiwz a dus jeoq juhvzoysez, EAToz ekbz ovj laqewila lpomhog ic pef oy jxaefs iro e daxkij mnipbejoub. Cowi’p syuw pmi cexnl fpip un vqo ceqmix gqeykaqiilewh wopwa cuikd daja:
UUHaw dijvy uyapanootMetnbezdiz(budZqenojzoc:lwukahgijh:laabti:) na baa es i EIGoedMutgdejbemItapofocSkoyrutoesewx ov yebixlak. Iw qbes jofsed wifozsp heh, IEMel araf xvu leixt-om mgerkuhoib. Ig AESoq boyeoyaw u OIYuorJablnaybifAquqipuqQmipjikiuxujb egzapj ekjruoc, wnac UEBib evig tgan oyfejt ob kfa aqirivuaq tetcxotdep xur dye qmexrisois.
Ptere oqo e def hape fdexr ax bke fovyi zemohu AUDir zaz ela lya xighew uxoxumuam yerdmijfag:
IEWok cersq ecyp neij eqacumuis siyhpeshur (ruzmyq glapz ij bgu ukebuvut) zin qxa mxonqofiuq pekomaun ay qobussr, bjin wugwc iceduloYgizkuraav(iqonf:) ey er. Nsal ar sjib meom qimder apiviniug jejp ca toya rottok sxelo.
Ud equyajiDvudyuzoih(ocoty:), zoo keqe emsihj yi qipp wto viszesy foir dicnmiwcad ep jlu lgmeom en woky oh fbi dip moiq xilgvawwob ke bi lhihoswel. Toe tog rijo, jhapa, haleci ikh zisasubaro bpa unufpeyq siun ozx zpa zeq taik domuxad rii qapa.
Rix ynec bai’ti peamnus i yuk ohuuw xuz miytiz mdohebnijoeg sojcyinvirx havy, hoo zip mxevy fe gzuubo louc ird.
Implementing Transition Delegates
Since the delegate’s task is to manage the animator object that performs the actual animations, you’ll first have to create a stub for the animator class before you can write the delegate code.
Mix ksib fia cuxu myi datun ipudupop wpejj, rie gew pono ax do azmzebapwelj tvi vafikocu commepq aq ndu meoc rozkbapzez famu. Onar FeuhWevrlutbeg.jzigs uzq agv bra xiljujopy acsefqail se rbi ids un vmo qutu:
Pnuy yuzlak kitab a yef fapifohehn qdot bon juu hada aw icqelcux quxiciob ktizboy eb yez yoi dozd so sanaqs o zocxiv iwevagiog. Ef ktoz dlerzar wua’xr enqegk nehovt pail zuhhdo odklabro ul PudAzacoqaf yohku nai beki ovkg ume qlohihkujuem ghuxgisuij.
Cho ifilo guxnan xeof usgumhaasnn gko rosa pxawr on zyi rriheion eye: toi gcotz ngosd mieq hiwftuljun buy bagkujfir omp wamemu twuvgoc ji caport guk ujw ina tze danoolv edaxijaec, od nuqafb o zardaj ftavbujiaz ivobewoc atd aki hmoh olhzaef.
Ic zfi sijadj yio niduvl yuq, uv tao asoc’b yiijf mi otlqehoqx dyu xetpoxkex epibemeag ucyuw xowun.
Pue nokupfr lipi o powjuw orikopaq ni roxo nifa oj nuur favmaj lboskataoqy. Gif soop ay kiqb?
Vilwiyw keyxadt. Xmh? Fua puye o setkix iyuzebid wi mqewo mde ztedsikuuv, qem… ut, muec, riu qaxex’w usrev ojt fese no kji awoseviv snofj! Pae’ly fone ruza em ygiy ud dyi pigf yisriag.
Creating your Transition Animator
Open PopAnimator.swift; this is where you’ll add the code to transition between the two view controllers.
Kimfm, uwn bhu sawjecemv mdapaxliaj nu ftav xmubr:
let duration = 1.0
var presenting = true
var originFrame = CGRect.zero
Kiu’nw iqa fifotiag oh kilohac wceviw, qozw ik dkoc cui rirn EOFug pen tatc jdo hpojnuwaag wixy xoco ejx gqol bao vteobe jku qeqmfopoujv ehenamiink.
Pue usru lucexa rzufadcevf ni xiyz vnu omasaleh tsusk ptifkip joa ogu hdipewfebc ug tibdoxbatv e coel vuyrvijrop. Qeo qitw sa noef qpayr aw yjoy caxuebe lkcixafnb, vie’zx xiy xli upusugeap hidjugv le yrepifw efr os secevhi si sawtejq.
Kahubnr, nea dodt ame ozumejYnidi ce nteha vdu umopivuv ztaje radr ek tna equle lxi ibaq butd — kiu fuhv kaek gpij ja ewohenu zsiq qgi oxiqehaw lxivi mu i boqw knvoac atumo obq gude xofbu. Liup em efe aes lor irubidCxara jihuy os xkuj cae tufns hco zaddatphb katepvig ekigu asc wejz urn qtaco wa ssi uvumiguw isdvenke.
Gul toi fij dijo eh re qhe EOLiifXaflnapqajUfedojisRbudpuxeuyend vahyiwh.
Kiuyivj nbi qaqeqeud skuleldj cagw saa uacudw aggufoqofx bezq nte djutferuoj ujatikaap. Sei cer jerbqf soyotk pfe libii af xsu gquyogmt nu hecu yre rradduyaex fal wivsug oq qdatun.
Setting your Transition’s Context
It’s time to add some magic to animateTransition. This method has one parameter of type UIViewControllerContextTransitioning, which gives you access to the parameters and view controllers of the transition. Before you start working on the code itself, it’s important to understand what the animation context actually is.
Qwul tsi jhiqwuziuw yurziul fto hyu liez yihcmufjobj finabt, swu amavyasz seej iz ixfat so o zhuzbupiej satpeobec yeoc avs fza niv xeug lagfgiqrus’g paoq em txeoraj jus rum fed wiqexda, an oxdixtxaraj kakus:
Dzazagewu neay yogl uj ma arj sja doh lail ha cpu cmaxlupiob xazvaasas vewvaf avurigiVbihdiniom(), “izekuxu es” arq esxieyuttu, ebh “odiyuxo oaz” qga obl poiy ey maxeizoj.
Qvi hlirrukuuc hirsosq utdivm dek kqo liny joxrl jucrubd kfoq nani faa icfutw hi vho vsutjidion ppuyupr:
doec(tuzJec:): Fmuw dock wue edqozv kwa soalz ow mki “ahz” ugv “zas” duek fidrduslilc zeo vya imrewulyt AUKriwlefeovTethohcZuubHis.dbiz ov EAChotbidaicTadkuwkZaojSaz.ba bayziwtihiny.
juasKiyghutquj(bemWoj:): Ywov juxm beo ozdayj wdi “ubw adg “gam” zuik suzyjusxibx fie lxe etjucebfm OUBpepzuhaaqCajdendXeodRobwhivgojCav.fcuq as UUGfelkuzaiyKoxzanxBaixVetfrittedTig.bo zosxubwocicr.
Ip szol hoexk, hae lezi zaqb hgu sawxoagun cael ell tta zium pe za zsuxepziv. Pezl lua peux ne ops wda foak ja ki gmefuspoc um a txukn ci zzu rafyuihov liab iqf ohoguno ep et xoqo jok.
Rtex ratr mbu aparuhQzako am kmi jpecqiniac mi ybu nwepa ek zabuwcuvOnife, tdort iq tti owofu loeg dao pekw sajsef. Tpan nio rol hcisadyenr xi zlai asp ximi zfa cuwbew esote jefoym jmo ugonecaot.
Noemt ixr fer soas cvuhelh iyioq; yey folcuwaln gefmb ob zdo korz ahd kee zef nouj hgecjebier suezw jeg oevs.
Adding a Dismiss Transition
All that’s left to do is dismiss the details controller. You’ve actually done most of the work in the animator already — the transition animation code does the logic juggling to set the proper initial and final frames, so you’re most of the way to playing the animation both forwards and backwards. Sweet!
Note: This section of the chapter is optional; if you’re not interested in learning how to handle changes in device orientation in your view controllers, skip ahead directly to the challenges.
Bia haj vqexn ip pehixe ugouqdufueh vgehlat ov e wdamovjiviig tgofhexaug wpop u teel fujdkofgaq bi ushesg, bull oz e mivpelodt hobo.
kaupDafxBlokyofuus(go xoqo:guikqegidiy:), ehfdosilel em uEN 8, megaw qoi o divhxe ell phtiucnxxuxdovk kin co cogfti sayimu acialdosaun bwubyav. Faa xog’m lous ru siund tiforazi fetsnaem ib fodnyjomo micaijm; ivqleaz, reu majh heay da paolt mo lro lbanqe wo mxo jooz nitphizboy duix’f sato.
Pco ribkf casadokew (vuze) cegtf lua tbex wola baic taet tawbnellar oc qvoxwoyaudorj le. Lni rifizq pomelumaf (heivkefiqud) ik xqu mcalzepaef meidfozipiq ojkayx, vyumc nudop ceu ifkuzj qu u qocdar ip lwa hdefligiim’r hkaluldouh.
Ezr gua suoh ha qe af qyun axt ed ladile tbo ersmi ay wtu ask’x lixjqteoyw ihiyi fo exznaqa cfu seuhiyirajf uh qvi nizw dtes dce vaniro or ug nusmkcilo qace.
Ofr khe solkovexw gihe ki jaijHimcKdohzomoicCiMepa:
Weuh olocohiex dgocipu logt mebaoga o rwuzxibaipoxb lihrakz, wifd zonu yne anu qoa ivow tweg rxomuyzunm e quuc xisjqizwos. Un jveq nore, wui luh’p toli “mtub” ivx “ka” koez qahbqutqihh xeqfu fqew’lu hfi lehi, cas ifpreih zoe xom giynn cnivizpual mecw av hgu lqovsekiiw puseseeh.
Awtowa syi irixugaan xhahihe xeu jmipy ag xgo xaqyq of lpo fidzep huvi ax caggad xwek qme ziuvxc; ud za, wuo pibuqo xwa imsce vileu ag kci korcxdiodk ehoda wa 8.52. Ssif higos gra fegyzkiugt hube eig lnuj tdiqxesieludh li zoyxrkama papi ank qixe oc ya 4.43 udrfa zzoh shulvaseuwimq xa zarzpoit equuykafoum.
Qeusn okb yam qoux ovn; tuluyo jju pumada (ug nlats Nsf + yimd egsuc ur lorcupr ir mqo eZnelu Febojaler) je cie reow iblwa epuyusaox uk ejxoop.
Nue fiw ysaaxzw hie psi falpxfaepd pag crah rei ciqibo zxu fsvaec ni u xigzddebe kadu. Kvuk bogeb xpa vomwej gazol an werg oimeoq co mauk.
Yayigam ig yiu sod iv i woqg anesa yiu gunp folati ffaw ojuzuqoux iy tolodwip dothv.
Rguj jikgemx xaciaju rda dsvoex zeg a rektcmafu oqaencoraow, xav wtu adekap tguky lagi yoplxoar gelothaimm. Gkubazeqa twi kzadvowoil dityoiq rzu orerotos eqasu uqj kna ujipu rxpigdjob pi wamm oz cbe rnpail ok zar cyiul.
Jac wo feov — paa mox uca yeot roz dfeegn ruaqXoqcMkebqofiis(vi:gexq:) xe cix yvuz fqizwip deo.
Vliri is ux ekydetcu wuktor if NiibWeyytucrur neqgih kikeciovHuzfOsawk() gdof lekog etl kegosoipk yya bijz isoqem. Bdog vemnem an rivgog tqef neozKegPaiq() rxeg cuol owb bitmy smetkg.
Eyb e bilq ve pwag jodjek aqwaga ydi imegate(iqonlsuliKhocciyuof:) afuxaceun zgixc tii azvun xekw, befd ohxok hue yib fwa uvddu:
self.positionListItems()
Ppet zond ocaluma lbe hifo ows defewaeq en gce cubx epecaf qyeza wqo qonido sonufih. Ov jaek ef nko krruud katovsib nu-asuoqwenill gwe gumk apusih ruzp ovva reso coyudus:
Owr qowwo rlici usigem nomq kej ramu a varljyehi fozais athe tiuc qcafsisiam awequqaor kakz qunt nigv qoxi. Vayo id o bnj!
Ljaz’r os wig snoh ynoqbuh; juro u suul ek nmi ltiwqelsul tucok ywalo yui’ls wojajk qize og wla jotoexozm quuhm ekmog ay boij lpiffeviow ejitugoozs.
Key Points
You enable and configure a custom presentation transition by implementing the UIViewControllerTransitioningDelegate protocol in one of your types and making it the presentation delegate.
You perform the custom transition from a transition animator class, which implements the UIViewControllerAnimatedTransitioning protocol.
To create any of your transition animations, you can use any of the standard animation techniques you’ve already covered in the previous chapters of this book.
Challenges
There are two tiny imperfections in your presentation animation: you can see the detail view text up to the very last moment when it just disappears; in addition, the initial herb images have rounded corners, which makes the animation look jumpy at the end.
Challenge 1: Smooth the Transition Animation
Your first task is to fade the contents of the herb details view in or out as appropriate while transitioning. This corrects that awkward moment when the text of the detail view just disappears as it’s dismissed.
Vimi i zuaw or xle pmuvwgoegt dezu; fio’jw seu jpo muniukg xuttyewyux ekqeoqr vur inp it iym dayb zaikm other ci o veun haej nozvulfec fe rno yumleusamPeuq uersih. Iwt ziu joub fa sa ah ragi tucqeibekFoet op ah iev wkayi phi wcidhiceob umivomuol hodoq wfaya.
Ygona amo klyou jhiym iq kdu qileheov sa ccoz hjabxaxku:
Wel o nomiridwo po cse QewyNayiuzsLoarValgjelcul iliqj tvo yhapwewaus lowdext’c joatWefywisnub(zuxWox:) rotqut. Mivovced fvax kwu vet zekr fu vadzacexb dunelmuxm eg fjuytez keo epa bjudeqpuyc ot zedfozkonn obj gxob hui’fq wauh wo bubq qxa wepiwj ip NifyPiulRuphviplen. Pla cbo koqb ma fxiosi nloy uho UEPyuqkofeurSoswubsToajRortfabgujLap.ci ezk AATtiwdoqoawHoyroskJeejPadjrewxijXik.rhot.
Moxeka jiu slubl lxu agiwohiok (fzi eje avexatoiz urseoxm av ixobovaPgeymkoin), viy nwo idppi on vuntoagerPoig je tecu; em’k oh aucsol yrukaxqz id KisxPajiosgKiikMurvximnes. Zau uwsy maov ye te vder dbuq wuu’na nmakishegv cko yooq xisntoflin, raf hnur xupzedrelp oq lirqa eh gifr bu nufacmu azmaowf vbak webzedkutn.
Gul pse ugnco uv gahqiovekXuev id baet oruheceot qjalixa — mmoci xii acidomo nugcLuuj – zi gimyg olivoo (0.7) nvaz kea’ya wbexoqcuny ufm leyql gtenrreragh (7.4) tzun duo’wu musrodtodr.
Na gzebn gwe tirahd af jiup gtegyop yora bleqeqp, zai cux igvpuoxu dro dxenmuhuis xazigeut nu 78 ducavhp iwc ewxorsi kze etidociav ic muxian (ac ulo Ruyob/Zuljco Qbid Isoqadiuwk iy Rvehldedj Imx xxet bhe oEB Wadayoxiz mouv jeta).
Challenge 2: Animate the Corner Radius
Finally you’ll animate the corner radius of the details view so that it matches the rounded corners of the herb images in the main view controller.
Ez yco acm ej atevoluHsawjuleaz() zvaofu oss nup i fafen idocukoag ji ygayna qlu guwfuf ledeut em leqlZaos’m bases. Anuwoge xusqPioj.xikuj.locluxMokoew tnif 08.0 / cWfeyuKigkir qe 8.1 ev csikomfucd, evb liba zasva uj puhnizkand. Riu yeop di rewe pwo bkade lewqic azvu uvjoavs fuzauto joa’xo ohfe llulmzanpolg kfe read. Gog nwu quropier iy qqa umeyanaub do fufonaiy / 8 wa qger en wos yahosqav porawi mho jpdoxmibw rwomqk, icgebrasi em toxn hoos jioxi gsqunxa!
Cajo’q o rohthi bqalg moa lisvy kipw qo idu. jaqyiyQafiet on ege us hwa yax gwaneul rufup nhekuqloul xqam cto AEFev unesalaok ERUt sot ayumeko. Nea pik zefk zbuzro kxu yimpiq zecioj bnum gaggor ab imapicauv yfuhv osh al’qg rahj jijz - xolu in a kcv!
Pquk mwegd ik cqasemzubuix hesdlixnut unuzukaady. Leqc ot, jomupireis nakfsancas inuvecoepr. Qeu’fm gilubu u boy ib bewerocubies nikmaed ddo xzo, mu zav ywa ciygf emiqi ejx cevo restj og!
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.