Proper way to implement a custom UIViewController interactive transition using UIViewControllerInteractiveTransitioning Delegate Protocol
1) The easiest way to tie a gesture to the UIViewControllerInteractiveTransitioning
object, is making it subclass of UIPercentDrivenInteractiveTransition
. Then where you implement the gesture handler, you call updateInteractiveTransition:
here an example with code:
-(void)handlePinch:(UIPinchGestureRecognizer *)pinch {
CGFloat scale = pinch.scale;
switch (pinch.state) {
case UIGestureRecognizerStateBegan: {
_startScale = scale;
self.interactive = YES;
[self.navigationController popViewControllerAnimated:YES];
break;
}
case UIGestureRecognizerStateChanged: {
CGFloat percent = (1.0 - scale/_startScale);
[self updateInteractiveTransition:(percent < 0.0) ? 0.0 : percent];
break;
}
case UIGestureRecognizerStateEnded: {
CGFloat percent = (1.0 - scale/_startScale);
BOOL cancelled = ([pinch velocity] < 5.0 && percent <= 0.3);
if (cancelled) [self cancelInteractiveTransition];
else [self finishInteractiveTransition];
break;
}
case UIGestureRecognizerStateCancelled: {
CGFloat percent = (1.0 - scale/_startScale);
BOOL cancelled = ([pinch velocity] < 5.0 && percent <= 0.3);
if (cancelled) [self cancelInteractiveTransition];
else [self finishInteractiveTransition];
break;
}
}
}
This code is from https://www.captechconsulting.com/blogs/ios-7-tutorial-series-custom-navigation-transitions--more
2) The function animateTransition
of UIViewControllerAnimatedTransitioning
is used to perform the interactive transition. It is automatically partitioned in "keyframes" thanks to your previous call to updateInteractiveTransition
. But I suppose that if you implement your startInteractiveTransition:
method of UIViewControllerInteractiveTransitioning
(so without using UIPercentDrivenInteractiveTransition
subclass) then you are responsible to manage the fully transition (not sure about that.. sorry but the documentation in my opinion is not really clear).
Apple does indeed provide an example project now for how you can achieve this. Having said that, I don't think it's the finest/clearest example, but it should get you on the correct path.
They also have a WWDC video that takes you through this very project.
Be warned that it's a fairly complex example, but if you do manage to break it apart and understand the various pieces, you should be equipped to deal with more or less anything on the transition front.
Essentially, the project splits the problem into two helper classes, 1) an AssetTransitionController
that is initialised with, and exists for the life of, the view controller, and 2) an AssetTransitionDriver
object that is created at the beginning of, and exists for the duration of, a transition.
The AssetTransitionController
is fairly simple, it conforms to UIViewControllerAnimatedTransitioning
and UIViewControllerInteractiveTransitioning
managing the lifecycle of the AssetTransitionDriver
.
The AssetTransitionDriver
is a simple NSObject
sub-class but actually ends up far more complex. It manages the main UIViewPropertyAnimator
, creating the view hierarchy for the transition, and responds to the interaction driver (a pan gesture recogniser). It also vends its animator to the AssetTransitionController
when requested.
It doesn't use UIPercentDrivenInteractiveTransition
at all.