2015.11.19 lots people says shut up and show me the code. Demo project
2019.02.21 Community Contributors' projects:
This post is aiming at the topic of UIViewController transitions. The gif shows what we are 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 are the foundation of customizing 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 are 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 leave it blank as well, what
mustOverride() does is throw an exception when we forget to override the method in subclasses.
BaseAnimator do only one thing, it determine if it's presenting or dismissing and call the 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 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.