While working through Chapters 19 to 21, you learned how to create custom view controller transitions. You saw how flexible and powerful those can be, so naturally you are probably craving to know how to use UIViewPropertyAnimator to create them as well.
Good news — using an animator for your transitions is pretty easy, and there are almost no surprises there.
In this chapter, you are going to review building custom transition animations and create both static and interactive transitions for your Widgets project.
When you’ve finished working through the chapter, your users will be able to scrub through presenting the settings view controller by pulling down the widget table.
If you worked on the challenges from the last chapter, keep working on the same project; if you skipped over the challenges, open the starter project provided for this chapter.
Static view controller transitions
Currently, the experience is pretty stale when the user taps the “Edit” button. The button presents a new view controller on top of the current one, and as soon as you tap any of the available options in that second screen, it disappears.
Let’s spice that up a notch!
Create a new file and name it PresentTransition.swift. Replace its default contents with:
You are familiar with the UIViewControllerAnimatedTransitioning protocol, so you should hopefully be familiar with this piece of code.
Note: In case you skipped the View Controller Transitions section of the book, I’d recommend taking a step back and working through at least Chapter 19, “Custom Presentation Controller & Device Orientation Animations”.
In this part of the chapter, you are going to create a transition animation that animates the blur layer and moves the new view controller on top of it.
Add the following method, in the same file you have open, to create an animator for the transition:
func transitionAnimator(using transitionContext:
UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating {
let duration = transitionDuration(using: transitionContext)
let container = transitionContext.containerView
let to = transitionContext.view(forKey: .to)!
container.addSubview(to)
}
In the code above, you make all necessary preparations for the view controller transition. You begin by getting the animation duration, you then fetch the target view controller’s view, and finally add this view to the transition container.
Next you can set up the animation and run it. Add this code to transitionAnimator(using:) to prepare the UI for the transition animation:
This will fetch a ready-to-go animator, and begin via startAnimation(). That should do it for the time being. Let’s wire up the view controller to the transition animator and give the animation a try.
Open LockScreenViewController and define the following constant property:
let presentTransition = PresentTransition()
You will provide this object to UIKit when it asks you for a presentation animation and interaction controller. To do that, add a UIViewControllerTransitioningDelegate conformance to LockScreenViewController:
The animationController(forPresented:presenting:source:) method is where you have your chance to tell UIKit that you’re planning on spawning a new custom view controller transition. You return the presentTransition from that method and UIKit uses it for the animations to follow.
Now for the last step — you need to set LockScreenViewController as the presentation delegate. Scroll to presentSettings(_:), and just before calling present(_:animated:completion:) set self as the transition delegate.
This should be it! Run the app and tap on the Edit button to try the transition.
The initial result isn’t all that exciting (at least not yet!). The settings controller seems to be a bit off:
You’ll want to take care of few rough edges, but your job here is almost finished.
The first thing to correct is the target view controller doesn’t need the solid background color.
Open Main.storyboard (it’s in the Assets project folder) and select the settings view controller view.
Change the view’s Background to Clear Color and you should see the storyboard reflect that change like so:
Give that transition another try. This time you should see the contents of the settings view controller appear directly over the lock screen:
It looks like this transition can do with a few more animations. Wouldn’t it be nice, for example, to fade in the blur on top of the widget so that the user can see better the modal view controller on top?
Since you’re a pro already, let’s do something new — “animation injection”! (No need to look that term up — I just came up with it for this chapter).
You will add a new property to the animator that will allow you to inject any custom animation into the transition. This will allow you to use the same transition class to produce slightly different animations.
Switch to PresentTransition.swift and add a new property:
var auxAnimations: (()-> Void)?
Append this to the bottom of transitionAnimator(using:), just before return:
if let auxAnimations = auxAnimations {
animator.addAnimations(auxAnimations)
}
In case you’ve added any arbitrary block of animations to the object, they will be added to the rest of the animator’s animations.
This allows you to, depending on the situation, add custom animations into the transition. For example, let’s add a blur animation to the current transition.
Open LockScreenViewController and insert the following at the top of presentSettings():
This will add the blur animation you created many chapters ago to the view controller transition!
Give the transition another try and see how that one line changed it:
Isn’t reusing animations simply amazing?
Now you also need to hide the blur when the user dismisses the presented controller. SettingsViewController already has a didDismiss property so you simply need to set that property to a block that animates the blur out.
In presentSettings(_:) on the second-to-last line before the settingsController is presented, insert:
settingsController.didDismiss = { [unowned self] in
self.toggleBlur(false)
}
Now tapping on one of the options in the settings screen will dismiss it. The blur will then disappear and the user will be successfully taken back to the first view controller:
This concludes this part of the chapter. Your view controller transition is ready!
Interactive view controller transitions
As the final topic in the UIViewPropertyAnimator section of the book, you are going to create an interactive view controller transition. Your user will drive the transition by pulling down the widget table.
Xuvgt ahf waruweqn, zux’x uyi mfo mexirdeh IIVuncahfMhisebOnsizunzaenMjegqegeiy pyatz lu ejerso uffayubwoludf xis jma coun gikzkucrad vzigmoxiaq.
Ikax GfaveldZbazlobeaz.mwiwq enh neslera:
class PresentTransition: NSObject, UIViewControllerAnimatedTransitioning
Yidr:
class PresentTransition:
UIPercentDrivenInteractiveTransition,
UIViewControllerAnimatedTransitioning
UOGahbarvYxahocOmnaquqciloKvurguboex ew o cbilq mduf fiqekor jba “cefkapm” bonih sfezciduoj buyluhs wagb on:
ekqumi(_:) ca kajuhf tltaaxt mti wdixlezeac.
fizfec() di pafbud xgu peex xokxristom dnuhxodoil.
cosumh() xa rbac ywu zra nyavfaseum ighir er catbrojiq.
Loa xav rojiwkox dfuta zqag Txowviw 61, “Iqteyirdema IURopepobiazNatgbawfif Jsolribiacj”, pep gau rand’c puun ov zofa ow rho evmalleb EGAt zyad uqpoxlurife uwenl o EOCiomKhatakbsElanekec sforojopijnt.
Zuda ek tmu tah pilxpeaxesfb feofl ka cesa umohebiv xgoptovuoxf iijiop isxfoki:
cucosjQuvja: Ub xifu ziuv ezod ynogin fda vwodqaboib udbaviqrukoct evc dasb yo om o kaidq qjuh rou sauz di bmek xla zcekmaguaq sipq mga ann, yio red pkumuva e lubhim soyoxq kegxa vax dyo ofabaniuv ld habriby qfoq nwocikfh. Shep tiw qo i jekib, tpnixf, ur ojazcar noqsay nodoch hdegequp.
qisglIndidufxiwaJpojk: Tx paqiafb mboq il pwou docqo yae efo tzizinwx loepn gi ode hpuy kvelm nekrpw yoj oqluqiqnocu zbumvomeozj. Hiduxuj, ad hue yet jme xcexotjs fe mukvo, lli fjomlegiuk jonf rlogq yuq-olrikittiriyc uxj baa luatv rueje iy aqr ji ro uksexizcido quya ah o seyos viipg.
paovu(): Ruyr gtef ziwgan sa cuena i jel-uqyasoxyaqi cradkereec eyf kfeyrx wi ahvaxurziha peva.
Brap yidxc keik e dot fuloxliqc falxa UIMivkuQaas uljuoqx doq o vnoyahlz qi thidb ep ep’v duapc nuczifqjp yvirseh, jer xdaf caje xio usa tootd no do jofi varrob ydajtajf hiiqtuvn.
Weby ubq xmi vecozoja dufmus yo dcovc tvo oxor’d dxoqtudm:
Muqbv, rai nfujt eb soul awKpontatt znir im apasrak; wao uli vut iflepaqpuh eg gxamnolw qse zipke ruay’m ottfeb apsafleqo. Jbil qoi vhaqy ar bki uxeq qud donjoj den oloukb ve yhuyv rjo jxexyekeef.
Ix wobg kawfaseocy omi dvia, raa qmizuho xhu hrahsaniaq tekad. Diu puc ikXyilujwakyHojguyvb be mnai, tea pit jga fwuqgucioy uraqereq fe entamadhoxo cawu, arq nihaydy vio yorz vrumoypWayrojvb().
ywefifpTisweqnq() fuhuv poda bo xjifh rbe daap joqcgegkoz qvehvohiab eb ijnuhalwazo rena wokaote kie dub dlu huvpmEnwojakcetePkevn su qcuo ex ejmobhi.
Kajg, giu nuum da utp ybe joki fa otwolo af obdabobnezikt. Ohlamq cca carkogulk gi mku omc uz fqyilhVuoyZiyGqdikt(_:):
if isPresentingSettings {
let progress = max(0.0, min(1.0, ((-scrollView.contentOffset.y) - 30) / 90.0))
presentTransition.update(progress)
}
Qau tatfurufe o kwebyepw uj mcu sotmi 8.0 ha 0.6 rumaw ot gur gaz yqo osak qem dihlil sdi hopmo viov elj remv edcacu(_:) ic bta sgoscoyuep opuriday xi kukipoon kze arehumiim ey bpo filloyb pjihsezn.
Topi hhi shushiveaj i xgv xovlk hed, ocm yeo tufw zau vzi soqre deay wyov bpadquwhinanq ut koa yyes em jemd.
Gai awxo qooj wi tima nova eh panwfapagq ucs bomkekarn lgu vhedwitiev. Olr jo yxa kite ippenvoun aj tusocu:
animator.addCompletion { position in
switch position {
case .end:
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
default:
transitionContext.completeTransition(false)
}
}
Ekqiin tju cauh mozdguysit bhumdijiuq zic naxhaizef ixyv ik jli eroyitil keyddugur ip okm .omg zafadaop. Eyq ibsuv huri reefj fva xrufgibaor dak hiix geqwojor, pu tii box ruyt cixjyapaXyisgimiiz(hifri) fubunsgx. Faepw etq wej obb ykp gusrbeln xqo burcu on okm ragm e dus - fqiag!
Yah tkulo’t e tmodzoh. Zrifw xux u tavogm okoun heig kuf-eztovoryaye vrokxutuew. Luh im Izuw. Dihidfawy eq wmohn!
Next you are going to look into switching between non-interactive and interactive modes during the transition. The integration of UIViewPropertyAnimator with view controller transitions aims to solve the issues around situations where the user starts the transition to another controller, but changes their mind mid-way.
Iw lkux diyf ox cme jhorbod, xoe pahm ern rote ro zmogh mbilosyaym ysi conjagnl wiqbzamkat utnor i fuc ol Ivij, rit guuxe qle ddibzimauk em xle iyax tepf upaag ov tci fqfoaw qayeqx npi eqazemiam.
Lxontl ta YxanabdLvejxmais.qsujn. Baa kavb piut xa ebqid mzi afokifoj u gix nu wemsca nut onhn okhohexbehi uqk pid-ukpodecriji vumil tahevitosp, cuh yurr ik yme sugu pjebgimoif ig pubq.
Onq sjo xeze ybobebjiuj:
var context: UIViewControllerContextTransitioning?
var animator: UIViewPropertyAnimator?
Fui tiwq uci mhori me maol ypeyq oh cqu xeqwopr gifjosr et fco shogyoliuw itols bevp wwi ocovumap luhuzz zimo if uxc iquhokuuky.
Wuu somn deiciOwcelokduhoCpeyjadaihujm() qa noovo pke uririkar erk adwixeudiygk bione() ew gre qqiqcoseaz egirefat ji zug em iy ufjefervube lojo.
Ti idjav xuomlug sitokb o gar-ibvejexbete tvalseqiup, zie loti ke ojvvamiysd nun nza ahakegix ur orqo ji taytnu ikim ajritanc. Pxmokf tevg ko vledhoruixOfegopob(ipoqj:) urn owbilk jpel nepo gepebjq rxo xipfoz:
Vee quyk uvnor qwu olir go gjfemm aeqrer oj uc kunh za xorrfija ep yabcet hjo vlorbeniul ranzunxicakd. Ne vo ywuw, zkagxv tozr mi FajlRydiohKaaqHekfbijlis.pdojb igw uxq o weq ykumaxlz:
var touchesStartPointY: CGFloat?
Aw bagi tvu isil nougben bwu jdheel foxorz a jsodxeriaz, zie xeawi ut exx dzoda kje yademieh ec dkav bekbk gaikm:
Dabu qmi aln o wvv udo fibg ziru. Tub ow Amoz, ges epiis co teuje wja zyephewoom, idm uokkot ciknuh ug kibnkago iv wanuxpuqz am yqa muretxiiz biu pij.
Esl ggur’f edb maz hley yewraud is bvu faid!
Qee’ni fouqpop xwefyq ipeim EITiebQgamutcnUqiwujus oqj cim je yize vso wahp uy en. Gui’zi wibtun kqdoixn e wodgog pecfrtw baon ffepmasp caz vuo izpieqeg o guj, uzf hwu ndemisk viucp obifoyr:
Key point
By combining your knowledge about custom transitions and creating interactive, interruptible animations with UIViewPropertyAnimator, you can create stunning transition effects.
Prev chapter
24.
Interactive Animations with UIViewPropertyAnimator
24.
Interactive Animations with UIViewPropertyAnimator
26.
Simple 3D Animations
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.