TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | Apache 2 |
ReleasedLast Release | Jul 2017 |
Maintained by Jeff Verkoeyen.
Light-weight API for building UIViewController transitions.
This library standardizes the way transitions are built on iOS so that with a single line of code you can pick the custom transition you want to use:
let viewController = MyViewController()
viewController.transitionController.transition = CustomTransition()
present(modalViewController, animated: true)
MyViewController *viewController = [[MyViewController alloc] init];
viewController.mdm_transitionController.transition = [[CustomTransition alloc] init];
[self presentViewController:viewController animated:true completion:nil];
The easiest way to make a transition with this library is to create a class that conforms to the
Transition
protocol:
final class CustomTransition: NSObject, Transition {
func start(with context: TransitionContext) {
CATransaction.begin()
CATransaction.setCompletionBlock {
context.transitionDidEnd()
}
// Add animations...
CATransaction.commit()
}
}
@interface CustomTransition: NSObject <MDMTransition>
@end
@implementation CustomTransition
- (void)startWithContext:(id<MDMTransitionContext>)context {
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[context transitionDidEnd];
}];
// Add animations...
[CATransaction commit];
}
@end
Import the framework:
@import Transitioning;
You will now have access to all of the APIs.
Check out a local copy of the repo to access the Catalog application by running the following commands:
git clone https://github.com/material-motion/transitioning-objc.git
cd transitioning-objc
pod install
open Transitioning.xcworkspace
Background: Transitions in iOS are customized by setting a
transitioningDelegate
on a view controller. When a view controller is presented, UIKit will ask the transitioning delegate for an animation, interaction, and presentation controller. These controllers are then expected to implement the transition's motion.
Transitioning provides a thin layer atop these protocols with the following advantages:
TransitionWith*
protocols.
This protocol-oriented design is more Swift-friendly than a variety of optional methods on a
protocol.In this guide we'll create scaffolding for a simple transition.
Transitions must be NSObject
types that conform to the Transition
protocol.
The sole method we're expected to implement, start
, is invoked each time the view controller is
presented or dismissed.
final class FadeTransition: NSObject, Transition {
func start(with context: TransitionContext) {
}
}
If using Core Animation explicitly:
final class FadeTransition: NSObject, Transition {
func start(with context: TransitionContext) {
CATransaction.begin()
CATransaction.setCompletionBlock {
context.transitionDidEnd()
}
// Your motion...
CATransaction.commit()
}
}
If using UIView implicit animations:
final class FadeTransition: NSObject, Transition {
func start(with context: TransitionContext) {
UIView.animate(withDuration: context.duration, animations: {
// Your motion...
}, completion: { didComplete in
context.transitionDidEnd()
})
}
}
With the basic scaffolding in place, you can now implement your motion.
You'll customize the presentation of a transition when you need to do any of the following:
You must subclass UIPresentationController in order to implement your custom behavior. If the user of your transition can customize any presentation behavior then you'll want to define a custom initializer.
Note: Avoid storing the transition context in your presentation controller. Presentation controllers live for as long as their associated view controller, while the transition context is only valid while a transition is active. Each presentation and dismissal will receive its own unique transition context. Storing the context in the presentation controller would keep the context alive longer than it's meant to.
Override any UIPresentationController
methods you'll need in order to implement your motion.
final class MyPresentationController: UIPresentationController {
}
This ensures that your transition implement the required methods for presentation.
Presentation will only be customized if you return .custom
from the
defaultModalPresentationStyle
method and a non-nil UIPresentationController
subclass from the
presentationController
method.
extension VerticalSheetTransition: TransitionWithPresentation {
func defaultModalPresentationStyle() -> UIModalPresentationStyle {
return .custom
}
func presentationController(forPresented presented: UIViewController,
presenting: UIViewController,
source: UIViewController?) -> UIPresentationController? {
return MyPresentationController(presentedViewController: presented, presenting: presenting)
}
}
If your presentation controller needs to animate anything, you can conform to the Transition
protocol in order to receive a start
invocation each time a transition begins. The presentation
controller's start
will be invoked before the transition's start
.
Note: It's possible for your presentation controller and your transition to have different ideas of when a transition has completed, so consider which object should be responsible for invoking
transitionDidEnd
. TheTransition
object is usually the one that calls this method.
extension MyPresentationController: Transition {
func start(with context: TransitionContext) {
// Your motion...
}
}
We welcome contributions!
Check out our upcoming milestones.
Learn more about our team, our community, and our contributor essentials.
Licensed under the Apache 2.0 license. See LICENSE for details.