- 2015.11.19 lots people says shut up (bad grammar) and give me codes. Here you are
- 2016.05.25 Swift version by ostathnicky
This post aiming on the topic of UIViewController transitions. The gif shows what we going to do. Present ViewController from ViewController by dragging.
What is it?
To be short, you can't actually drag a
UIViewController to anywhere.
What makes you feel UIViewController animate from here to there is UIViewControllerAnimatedTransitioning, interact with it according to gestures turns out to be misleading.
How to do it
There is no two
UIViewController in together, instead there's only one
UIViewController at a time. When user begin drag on certain subview, present another view controller with custom UIViewControllerAnimatedTransitioning by custom UIPercentDrivenInteractiveTransition protocol.
These two protocols is the foundation of customize interactive
UIViewController transitions. In case you don't know yet, take a glance before starting.
1. UIViewControllerAnimatedTransitioning protocol
2. UIPercentDrivenInteractiveTransition protocol
UIViewController implements UIViewControllerTransitioningDelegate protocol to tell which animator and interactor is gonna used by custom transitions.
mustOverride() is a marco took from stackoverflow Yar's answer, or you can use nicklockwood's solution MustOverride GitHub. You can left it blank as well, what
mustOverride() does is throw an exception when we forget override the method in subclass.
BaseAnimator do only a simple thing, it determine if it's presenting or dismissing and call corresponding method.
The trick is
initialY property, as you can see, the
UIViewController which transition customized will starts from
initialY and ends at
initialY as well.
initialY is where our mini view located.
At the time user just begin dragging, we present a new
UIViewContrller and customize our
transitionContext to make it looks like the same as last
- (UIView *)fakeMiniView returns fake
subview from last
UIViewController, you may either mock a new one or snapshot existing one, choosing a practice that fits with your use case.
Let's say we present
ExistViewController.m we declare class extension and implements UIViewControllerTransitioningDelegate.
From now, you got a customized transitions animator, and sets up by UIViewControllerTransitioningDelegate.
You should see your customized transition works.
Transitions response to gesture
attachToViewController:withView:presentViewController: is helper mehtod, encapsulate gesture bindings.
ExistViewController, create two Interactors of presenting and dismissing, implement
interactionControllerForDismissal: methods from UIViewControllerTransitioningDelegate.
disableInteractivePlayerTransitioning indicates if we want to skip custom
UIPercentDrivenInteractiveTransition or not, if you want modal or dismiss ViewController directly, then set it to
Feel free to comment.