iOS Animation Tutorial: Custom View Controller Presentation Transitions
Learn how to create custom view controller presentation transitions and spice up the navigation of your iOS apps! By Fabrizio Brancati.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
iOS Animation Tutorial: Custom View Controller Presentation Transitions
20 mins
- Getting Started
- Behind the Scenes of Custom Transitions
- Implementing Transition Delegates
- Wiring up the Delegates
- Using the Animator
- Creating your Transition Animator
- Setting your Transition’s Context
- Adding an Expand Transition
- Adding a Pop Transition
- Scaling the View
- Adding Some Polish
- Adding a Dismiss Transition
- Device Orientation Transition
- Where to Go From Here?
Adding Some Polish
Currently, your animation starts from the top-left corner. That’s because the default value of originFrame
has the origin at (0, 0)
, and you never set it to any other value.
Open HomeViewController.swift and add the following code to the top of animationController(forPresented:presenting:source:)
before the code returns the transition:
guard
let selectedIndexPathCell = tableView.indexPathForSelectedRow,
let selectedCell = tableView.cellForRow(at: selectedIndexPathCell)
as? RecipeTableViewCell,
let selectedCellSuperview = selectedCell.superview
else {
return nil
}
transition.originFrame = selectedCellSuperview.convert(selectedCell.frame, to: nil)
transition.originFrame = CGRect(
x: transition.originFrame.origin.x + 20,
y: transition.originFrame.origin.y + 20,
width: transition.originFrame.size.width - 40,
height: transition.originFrame.size.height - 40
)
transition.presenting = true
selectedCell.shadowView.isHidden = true
This gets the selected cell, sets the originFrame
of the transition to the frame of selectedCellSuperview
, which is the cell you last tapped. Then, you set presenting to true and hide the tapped cell during the animation.
Build and run the app again and tap different recipes in the list to see how your transition looks for each.
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 play the animation both forward and backward. Sweet!
Open HomeViewController.swift and replace the body of animationController(forDismissed:)
with the following:
transition.presenting = false
return transition
This tells your animator object that you’re dismissing a view controller so the animation code will run in the correct direction.
Build and run the app to see the result. Tap on a recipe and then tap on the X button on the top left of the screen to dismiss it.
The transition animation looks great, but notice the recipe you picked has disappeared from the table view! You’ll need to make sure the tapped image re-appears when you dismiss the details screen.
Open PopAnimator.swift and add a new closure property to the class:
var dismissCompletion: (() -> Void)?
This will let you pass in some code to run when the dismiss transition completes.
Next, find animateTransition(using:)
and add the following code to the completion handler in the call to animate(...)
, right before the call to completeTransition()
:
if !self.presenting {
self.dismissCompletion?()
}
This code executes dismissCompletion
once the dismiss animation has finished, which is the perfect spot to show the original image.
Open HomeViewController.swift and add the following code to the main class at the beginning of the file:
override func viewDidLoad() {
super.viewDidLoad()
transition.dismissCompletion = { [weak self] in
guard
let selectedIndexPathCell = self?.tableView.indexPathForSelectedRow,
let selectedCell = self?.tableView.cellForRow(at: selectedIndexPathCell)
as? RecipeTableViewCell
else {
return
}
selectedCell.shadowView.isHidden = false
}
}
This code displays the original image of the selected cell to replace the recipe details view controller once the transition animation completes.
Build and run your app to enjoy the transition animations both ways now that the recipes aren’t getting lost along the way!
Device Orientation Transition
You can think of device orientation changes as a presentation transition from a view controller to itself, just at a different size.
Since the app is built with Auto Layout, you don’t need to make changes. Simply rotate the device and enjoy the transitions (or press Command-left arrow if testing in the iPhone Simulator)!
Where to Go From Here?
You can download the finished project using the Download Materials button at the top or bottom of this tutorial.
If you enjoyed what you learned in this tutorial, why not check out iOS Animations by Tutorials book, available in our store?
You can also improve the transition that you’ve created in this tutorial with Reproducing Popular iOS Controls · App Store: Drag Down to Dismiss episode on how to create the App Store Today tab animation effect.
We hope you enjoy this update and stay tuned for more book releases and updates!