UIPresentationController Tutorial: Getting Started
Learn how to build custom view controller transitions and presentations with this UIPresentationController tutorial. By Ron Kliffer.
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
UIPresentationController Tutorial: Getting Started
30 mins
- Getting Started
- Core Concepts for iOS Transition
- Creating the Transitioning Delegate
- Setting Up the Framework
- Creating the UIPresentationController
- Creating and Initializing a UIPresentationController Subclass
- Setting Up the Dimming View
- Override Presentation Controller Methods
- Implementing the Presentation Styles
- Creating the Animation Controller
- Wiring Up the Animation Controller
- Adaptivity
- Overriding the presented controller
- Where To Go From Here?
View controller presentation has been an integral part of every iOS developer’s toolkit since the early days of iOS.
You’ve probably used present(_:animated:completion:)
before but, if you’re like a lot of developers, you’ve stayed with the default transition styles shipped with iOS.
In this UIPresentationController
tutorial you’ll learn how to present view controllers with custom transitions and custom presentation styles.
No longer will you be limited to full screen or popover presentations and the standard transition animations. You’ll start with some drab, lifeless view controller presentations and bring them to life.
By the time you finish, you’ll learn how to:
- Create a
UIPresentationController
subclass. - Use a
UIPresentationController
for slick custom presentations. The presented view controller doesn’t even have to know it’s there. - Reuse a
UIPresentationController
for various controllers, by tweaking presentation parameters. - Make adaptive presentations that support any screen size your app might encounter.
Getting Started
With the 2020 summer games a year away, a client hires you to create an app that tallies the medal count for the competing nations.
While the functional requirements are pretty simple, your sponsor asked for a rather cool looking slide-in transition to present the list of games.
At first, you feel a bit of panic. But then you realize you do have transition-building tools at your fingertips. You even put down the paper bag!
Use the Download Materials button at the top or bottom of this tutorial to download the starter project.
Take a moment to familiarize yourself with the project and the following elements:
- MainViewController.swift: The main controller of this project from which all presentations start. This will be the only existing file in the project that you’ll modify.
- GamesTableViewController.swift: Displays a list of Games the user can select.
- MedalCountViewController.swift: Displays the medal count for the selected sporting event.
- GamesDataStore.swift: Represents the model layer in the project. It’s responsible for creating and storing model objects.
Before you start changing things around, build and run the app to see what it does. You’ll see the following screen:
First, tap Summer to bring up the summer menu, GamesTableViewController
.
Notice the menu presentation is the default one, which is from the bottom. The client wants to see a sleek slide-in instead.
Next, tap London 2012 to dismiss the menu and return to the main screen. This time, you’ll see an updated logo.
Finally, tap Medal Count to bring up MedalCountViewController
for the 2012 games.
As you see, this controller also uses the old bottom-up, default presentation. Tap the screen to dismiss it.
Now you’ve seen the app you’ll upgrade, it’s time to turn your attention to some core concepts and theory for UIPresentationController
.
Core Concepts for iOS Transition
When you call present(_:animated:completion:)
, iOS does three things.
First, it instantiates a UIPresentationController
. Second, it attaches the presented view controller to itself. Finally, it presents it using one of the built-in modal presentation styles.
You have the power to override this mechanism and provide your own UIPresentationController
subclass for a custom presentation.
If you want to build sweet presentations in your apps, it’s mandatory to understand these key components:
- The presented view controller has a transitioning delegate that’s responsible for loading the
UIPresentationController
and the presentation and dismissal animation controllers. That delegate is an object that conforms toUIViewControllerTransitioningDelegate
. - A
UIPresentationController
subclass is an object that has many presentation-customizing methods. You’ll see some of these later in the tutorial. - An animation controller object is responsible for the presentation and dismissal animations. It conforms to
UIViewControllerAnimatedTransitioning
. Note that some use cases warrant two controllers: one for presentation and one for dismissal. - A presentation controller’s delegate tells the presentation controller what to do when its trait collection changes. For the sake of adaptivity, the delegate must be an object that conforms to
UIAdaptivePresentationControllerDelegate
.
That’s all you need to know before you dive in!
Creating the Transitioning Delegate
A transitioningDelegate
inherits from NSObject
and conforms to UIViewControllerTransitioningDelegate
.
UIViewControllerTransitioningDelegate
protocol, as its name hints, declares five optional methods for managing transitions.
You’ll work with three of these methods quite a bit in this tutorial.
Setting Up the Framework
Go to File ▸ New ▸ File…, choose iOS ▸ Source ▸ Cocoa Touch Class, and click Next. Set the name to SlideInPresentationManager, make it a subclass of NSObject and set the language to Swift.
Click Next and set the group to Presentation, then click Create.
SlideInPresentationManager
to be an NSObject
because transitioningDelegate
of UIViewController
must conform to NSObjectProtocol
.Open SlideInPresentationManager.swift and add the following extension:
// MARK: - UIViewControllerTransitioningDelegate
extension SlideInPresentationManager: UIViewControllerTransitioningDelegate {
}
Here, you make SlideInPresentationManager
conform to UIViewControllerTransitioningDelegate
.
In MainViewController
you have buttons for both seasons: Summer on the left and Winter on the right. There’s also a Medal Count on the bottom.
To make the presentations fit each button’s context, you’ll add a direction property to SlideInPresentationManager
. Later, you’ll pass this property to the presentation and animation controllers.
Add the following to the top of SlideInPresentationManager.swift:
enum PresentationDirection {
case left
case top
case right
case bottom
}
Here, you declare a simple enum
to represent the presentation’s direction.
Next, add the following property to SlideInPresentationManager
:
var direction: PresentationDirection = .left
Here, you’re adding a direction
and giving it a default value of left.
To assign an instance of SlideInPresentationManager
as the transitioningDelegate
for every controller you present, open MainViewController.swift and add the following above dataStore
definition:
lazy var slideInTransitioningDelegate = SlideInPresentationManager()
You might ask yourself why you’re adding this as a property on MainViewController
. There are two reasons:
-
transitioningDelegate
is a weak property, so you must keep a strong reference to the delegate somewhere. - You don’t want to keep this reference on the presented controller itself as you might want to reuse it on different presentation styles. Deciding the type of presentation to use is now the presenting controller’s task.
Next, locate prepare(for:sender:)
, and replace it with the following:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let controller = segue.destination as? GamesTableViewController {
if segue.identifier == "SummerSegue" {
controller.gamesArray = dataStore.allGames.summer
//1
slideInTransitioningDelegate.direction = .left
} else if segue.identifier == "WinterSegue" {
controller.gamesArray = dataStore.allGames.winter
//2
slideInTransitioningDelegate.direction = .right
}
controller.delegate = self
//3
controller.transitioningDelegate = slideInTransitioningDelegate
//4
controller.modalPresentationStyle = .custom
} else if let controller = segue.destination as? MedalCountViewController {
controller.medalWinners = presentedGames?.medalWinners
//5
slideInTransitioningDelegate.direction = .bottom
controller.transitioningDelegate = slideInTransitioningDelegate
controller.modalPresentationStyle = .custom
}
}
Here’s a section-by-section explanation of what you’ve set up:
- Presentation direction of the summer games menu is .left.
- Presentation direction of the winter games menu is .right.
- The games controller’s
transitioningDelegate
is now theslideInTransitioningDelegate
declared earlier. - The
modalPresentationStyle
is .custom. This makes the presented controller expect a custom presentation instead of an iOS default presentation. - Presentation direction of
MedalCountViewController
is now .bottom. ThetransitioningDelegate
andmodalPresentationStyle
are set as you did in steps 3 and 4.
You’ve reached the end of the section and have set yourself up with the groundwork necessary for the next big thing coming at you: the UIPresentationController
subclass.