#STPTransitions
Unified, easy API for custom iOS view controller transitioning.
Perhaps you watched the 2013 WWDC talk or read the slightly spread-out documentation on how to use custom transitions between child view controllers, modal view controllers and in a navigation controller. Couple of minutes in, you're wandering in Protocolandia and you're lost. We don't blame you.
pod 'STPTransitions'
(via CocoaPods)
- Child view controller transitions
- Modal view controller transitions (+ fix for landscape)
- Navigation controller transitions
- Unified, simple API
In the works:
- Full interactive transition support
First import the library's header:
#import <STPTransitions.h>
With STPBlockTransition
, you can quickly create in-line transitions
STPTransition *snazzyTransition = [STPTransition transitionWithAnimation:
^(UIView *fromView,
UIView *toView,
UIView *containerView,
void (^executeOnCompletion)(BOOL finished)) {
// Your fabulous animations go here
}];
Note: You have two important responsibilities:
fromView
is a subview ofcontainerView
,toView
is not. Add it when appropriate.- Execute
executeOnCompletion
when the animation is completed (at the end of its completion block).
To set up, assign the STPTransitionCenter
singleton as navigation controller's delegate:
navigationController.delegate = [STPTransitionCenter sharedInstance];
Now simply push and pop view controllers using:
[self.navigationController pushViewController:viewController
usingTransition:snazzyTransition];
// and
[self.navigationController popViewControllerUsingTransition:transition];
No setup is needed. In the parent controller, switch between two child controllers using:
[self transitionFromViewController:oldChildViewController
toViewController:newChildViewController
usingTransition:snazzyTransition];
Note: This transition currently cannot be interactive. If you'd like this feature, voice your opinion in the Issues.
To set up, assign the STPTransitionCenter
singleton as presenting controller's delegate:
self.transitioningDelegate = [STPTransitionCenter sharedInstance];
Now simply present and dismiss view controllers using:
[self presentViewController:viewController
usingTransition:snazzyTransition
completion:completion];
// and
[self dismissViewControllerUsingTransition:snazzyTransition
completion:(void (^)(void))completion];
To maintain thin view controllers and a nicely separated codebase, you probably don't want to keep your transition animation code in the view controller itself. It also allows for the transition to be reused. You achieve both of these goals by subclassing STPTransition
.
See the example project for a hands-on code example.
When pushing or presenting a view controller, you can specify which transition should happen when the returning (i.e. pop or dismiss) operation takes place. To do that, simply assign the transition object to be used to reverseTransition
.
This greatly helps decoupling, because the pushed/presented controller doesn't have to know anything about how it's being shown.
Pro tip: Just assign reverseTransition
to be a new instance of the same class you just created for the push/present. See below on how to easily handle both animations in one class.
As of iOS 7.0.2, custom modal transitions in landscape orientation are not very usable, because the views iOS gives you have all kinds of messed up frames and transforms. STPTransitions attempts to solve this for you, providing you a view in the orientation you'd expect. This has been tested and works for iPad full-screen landscape custom modals.
Often, you don't want to have two STPTransition
subclasses for the same type of animation, i.e. one for going forward, and one for going back. When going back – popping or dismissing a controller – the transition instance automatically gets assigned YES
for isReversed
.
Pro tip: Reuse code and handle both forward and backward transitions in the same class. Usually it means having if/else
conditionals on isReversed
.
A transition can have a gesture recognizer assigned. The transition gets automatically kicked off when the recognizer's gesture is detected.
Note: This does not mean the transition is interactive (e.g. follows users finger), although it can be.
TODO: Interactive transitions aren't fully supported yet.
- Set the
interactive
property toYES
. - Assign
gestureRecognizer
that is going to track the progress. - Implement
interactiveGesturePercentageCompletionForPoint:
in your subclass.
Note: An interactive transition doesn't necessarily need to be triggered interactively, e.g. it can be triggered by a button and happen non-interactively. The wasTriggeredInteractively
property informs about the way it was triggered.
If you'd like the library to include some configurable, often used transitions by default, voice your opinion in the Issues. Contributions are also welcome.
Q: I need for my UINavigationController
to have my own delegate. What do I do?
A: Subclass your delegate from STPTransitionCenter
and use your own instance instead of the default center. You're responsible for keeping that object around, as you're not using the singleton. Make sure you call super
in any delegate methods that are implemented by the center.
Created by Stepan Hruda. If you follow him on Twitter, he's gonna have a good time.
Thanks goes to Josh Vickery and ShopKeep POS for contributions and feedback.
Released under MIT License.