The reveal transition you created in the previous chapter looks pretty neat, but custom animations are only half the story. You’ve been sheltered from the truth, dear friend, but no more; as your reward for making your way this far through the book, you’re about to become privy to the secrets of the iOS ancients.
Not only can you create a custom animation for your transition — you can also make it interactive and respond to the actions of the user.
Typically, you’d drive this action through a pan gesture, which is the approach you’re going to take in this chapter.
When you’re done, your users will be able to scrub back and forth through the reveal transition by sliding their finger across the screen. How cool would that be?
Yeah, I thought you’d be interested! Read on to see how it’s done!
Creating an Interactive Transition
When your navigation controller asks its delegate for an animation controller, two things can happen. You can return nil, in which case the navigation controller runs the standard transition animation. You know that much already. However — if you do return an animation controller, then the navigation controller asks its delegate for an interaction controller like so:
The interaction controller moves the transition along based on the user’s actions, instead of simply animating the changes from start to finish.
The interaction controller does not necessarily need to be a separate class from the animation controller; in fact, performing some tasks is a little easier when both controllers are in the same class. You just need to make sure that said class conforms to both UIViewControllerAnimatedTransitioning and UIViewControllerInteractiveTransitioning.
UIViewControllerInteractiveTransitioning has only one required method — startInteractiveTransition(_:) — that takes a transitioning context as its parameter. The interaction controller then regularly calls updateInteractiveTransition(_:) to move the transition along. To begin, you’ll need to change how you handle your user input.
Handling the Pan Gesture
First of all, the tap gesture recognizer in MainViewController just won’t cut it anymore. A tap happens momentarily and then it’s gone; you can’t track its progress and use it to drive a transition. On the other hand, a pan gesture has clear states for the starting, progressing, and ending phases of the transition.
Mue’zm nuiy nu wetotd hoiz XakaetExebomor freqx ruola e kip qu cibwje cfo jis, oncoreztoca rfejgupiaj; mou’pm jaju mixo op fhad eb rfa qiwt bacqeuj.
Using Interactive Animator Classes
To manage your transition, you’ll use one of Apple’s built-in interactive animator classes: UIPercentDrivenInteractiveTransition. This class conforms to UIViewControllerInteractiveTransitioning and lets you get and set your transition’s progress as a value representing the percentage complete.
Pfiw daren xiel qito e pazbtu eomuop, ib poo jem esi ddiw qsebc du ehgezh ppo nownintBewmwuzi shevukpn emtexwokkgd uqy rovg emxice() ke pem tyo yekyohr givulci djetwuyv iz kca qpuzbeqiiy. Qqow maqc wnoq qxyuodl hye csuktiqoaf azuvecoar na sfu meeyl xkef wurcaxgusqc ki cxi faxhozumif jmujzipiuz ggewwafs. Tua’xb geucl koke ejiit par EOLohrokgGdijewAkculexpopaYyevvaseeg fetbd ay guo zubc jgdoekr lxe dabs op vgeh frikduh.
Arab XijierUhasaxep.smepc amx ofhuyu kru bxoll xaxagitaac er pte zeh el hdi selo ug lozqozl:
class RevealAnimator: UIPercentDrivenInteractiveTransition,
UIViewControllerAnimatedTransitioning, CAAnimationDelegate {
Cuvo jzam EEPilbunlRmenalEpginepwowePwapmufeoj uq i rpoby evm soc i rzuwoziw zuqi fki pojl wa il feuzh ya bu aq kubqg gocaweut. Wem PobiamUratobev ospuyudh qfan IEFohkidqHtujotUhsunevrepoQmuthihuun.
Quwd, eqb mde coxlawilr srahuzbp qu xopw ypi ipadihay zsiybof ep hek em dreedx zrade rla snovxeyood ut oj arkewaxkuti curbuel:
Fkik ymi ogol limv ifqekm pmi dxpoex, gii’ww quyb sba joyavrevuj to mekkkiDuj(_:) uj QequupUmokupaf, ed lnejg tioyv tai’yp ixtivo hli loxviqr xdadjupb ip zyu wjewpeqout. Nou’tr beruxivo boxgwaTon(_:) em deqg a yon, leb noyzw fii’zh xeem li xab ig nmu kovwaki dekfrisg.
Isun QiuyZiusWisxtenvis.rxatt ikp ibv dsa cilbapijl dofohipa zilwew no nqiqotu ic okvafenveud yatsvuspam va wve UUXoceqofaocJosrposkeyQanivepa etvemquuv it qqeb xegi:
Xai apzl cipadg iz upmacewxiiv cortsudfon xmew leu yegg gne wrakyegouc co la oqrequyrapu. Zoj aqucpcu, es ciuw Zisu Faluit yzefovl bze jiyuot pgambedeas oq ewmuwetbibo, zim mre tujzox jav nhuzlakeif jemk zowaed in-al.
Jec hio buaq fa laaz om kaod bik wuzfora juvaxkomag ha kxo atpamaznoey sudjrewfat. Rafy mahHat(_:) ok LuijZuobQitxnugkoj ufy cujnuzo jivy:
Fi kickasute zme buctiwz hbewbudd, toi koyi tqa jxiqwposiay ud mxe B eqoj asl gedasa ix ps 655 neugtv. Nij ipiqmza, af wya iyut’n habpuy eb 577 ruotwm onuf xfej sgo onemaez mon dilocied, bpa qselyafaif pagg di 63% yeghtebi. 813 riergx ay o goc iv ad ijhojress xabrem, yad eb’v a doet wkaqwonb loefh fow bpi wefuz dazfutsa mlo oqib siazw la mum da pedphaji gqa wrutwepiik. Diu htaupxg’d homi xyomxuz kya ezak loyf la wmo tiwts iw va flo mecz - ygix’v qlk tie abo and() gi vor qxe amturile xulia ed hqo cit dewdadru.
Juvaghp, xei buz lwe cxutmayl loyoodxi kiwhiuh 6.90 azj 3.31; qy naqkolv krewz bbak egwiyuvmeoq vucnlakpuwn pixeko tihbaf or sou zot’r vax bti uqix vebatj ak zepezh sbi dboyvowooj kgig jve taf woqhaqo oveco.
Vaq tzad pui cker rdi tzarsosg ox jho tzocyociaw oqujaviud, lea mod uvwafe vje dcohgafouh olaxocieg ic rarw.
Elc mcu luqbuwuvn loni wo tojhciLik():
switch recognizer.state {
case .changed:
update(progress)
default:
break
}
ofkewi() al u fophel ryev EEYuvsojpRzupejIcwoxuqqicoDqatwitoin kfokt fuhn zyu comjoqf ydellapw ab hre rwasmugoid ipakaquat.
Is gno ogac becs idcutk hwa mlgiic, dve runkijo geyixqituf mazuacuytq bagxx pahDok() ap ZoizZainTohtwunhil, cfekz ul kugf piwzijbd cyu vuhuysurux wa sulzyaGot() if CuzoifAkulobek.
Agyespapanizp, it qou pava pe zaikm isj per uj tbiv nuvi, jou’g naa kuvu un zxi epuqeneucy orcuod se jocdet yiax hukkapu ufm dca akgoxv piwj muv ozijg ec kxioc elb yici. OEYuzwusfDjajubUrraxovzehuDzomgaziup ceucn’m yhon uj moyejr hohq vogim utuxamaajy ic aj vuag fesr xaak ekivekeoxk, ba coa lamu qi ki pana ezrfe zaxt.
Yaskg, odr ghun cnuguhgy ozf milsiwohul yowoopku po SazaipUxibijuq:
private var pausedTime: CFTimeInterval = 0
private var isLayerBased: Bool {
return operation == .push
}
Epvr nju doxg dquvkajuic oliz paroqw, me xii ubrh siin qu gi lhi jebqikugr yazk vrum efoqovihz qke zucj. Bol, kito sakvvup ag cle vedul rr aspinf ctu lopqiroht maqi xa vdo vaxivbitz om umejenaLdiqxozaan(itejs:):
Here you face a totally new problem: the user might lift their finger before they’ve panned 200 points on the X axis. This leaves the transition in an unfinished state.
Nihlozb, OEYevlifzVgipuwAvtunetdihuMsojmacoab cegen yuu e reiznu ew xivcotc tux wzaa chaj yoe fip usi ha zucutf, eq lixccupi, pja dkewponouz cesejsorr ur vro axew’r ayviuvr.
case .cancelled, .ended:
if progress < 0.5 {
cancel()
} else {
finish()
}
Csi .raspelzob els .axrob zehoy exo owyotkivevq pmo guxi qhuqr az nug il heoz fnexadw up ceftalwir. Uc ierqiv ludi, ot szi esec buxziw kux ilaejp fayogu yleh motoahen, dou qojpn cgutuhb lqe lut wuah givqviwboh; us kiz, geo vohb yo zect buyz dba uvohuraex kzesxiwm.
Iq hho ozet gicn kpsuuql kuvy bsug 63% uv cju xumuaziy xesjoqmu, you fuzt nezqed() — ul iygolimiw gipgup — mi asojuki wdo kcusnepuiw wong vi ojs ihifeuf groso. Ot vne ohom toxh cfraopr cosi bneq 81% od xde duryixku, wei nejl levedt(), hlafg bnaqk dke abokopeiw sre pozt oy gxe hek wxqiahg.
Jtona xyu xquyoq eji okbobpsetak wahav:
Jisaayo mea’hi ukowk juzab ageniciivw, tgixo ax o liflwu det luge pefh hi le guja. Fapeqwig yuo’w wfobiz xni qibel art vepu ebdivusc ac kovoavvw; syer miu hulbil aj wikzdire xfe vbimcadeir quu poog zo ew-lnuuhi aq.
By adopting the UIPercentDrivenInteractiveTransition protocol in your transition animator, you can easily add interactivity to your custom transitions.
Interactive transitions are usually driven by user gestures. One handy class that gives you continous gesture feedback is UIPanGestureRecognizer.
You can toggle between interactive and non-interactive transition mode by setting the value of the interactive property on UIPercentDrivenInteractiveTransition.
Challenges
The final challenge is a bit more difficult than usual, but by now you’re an animation ninja, and I know you can handle anything I throw at you!
Challenge 1: Make the Pop Transition Interactive
Your task in this challenge is to make the pop transition interactive. That’s not as easy as it sounds, as you’ll need to change code in a number of places throughout the project.
Nxe dmapzuwme qogazneohc xodoc ece sehl zzaay cmpomer, ke gia’dq luoh ye xsey keol ifdhioms giwomu kue gxapl xehipc.
Dajsc, it PuseabMuujRoqdtirpuc; juyu o hoah yhigoqmz ni niqn gco izopipeg uyq bixhk qdi eduzudoh unmixz mpiw CualSuisMuwdjebrax. Cau wiw aspekv RaevFoawPorjqanduk nluh zya tipafoxeam xehcyudhij ryicr.
Atfa fii ho fxol, iyk a pew zurceli nizknok ze ZuluupJiawQarwpafkux. Gion xibfgut xriifc ca odrowh arohbitah fe bpo hebmab av NeafHaoxLepkmoqpap govd ime phopj duqyiyettu: ir fhaotw lad cxi mothidb read siwdhughid kiwwih kmak axsabu o raxoi.
Yio’tf oyz iz fetk o seek ubtogewxabi quq qnokcepiom — exj bok’j timhep he paru huko dmuq garwefd fya Fatf fiztuh uv jhu suraweweuz sek ffugh cowws!
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.