I want build interactive transition with UIViewAnimation.But there's few layer property that I can animate it.So i decided use the CAAnimation. I wanna change the ViewController's view mask,Here is the code
-(NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext{
return 0.5f;
}
-(void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext{
_transitionContext=transitionContext;
UIViewController *fromVC=
[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC=
[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView=[transitionContext containerView];
_toVC=toVC;
_fromVC=fromVC;
[containerView insertSubview:toVC.view aboveSubview:fromVC.view];
//Create the BezierPath
UIBezierPath *initailPath=[UIBezierPath bezierPathWithRect:(CGRect) {{_cellRect.size.width/2,_cellRect.origin.y+_cellRect.size.height/2},.size= {0.5,0.5}}];
CGFloat radius;
CGFloat distance;
if (fromVC.view.frame.size.width>fromVC.view.frame.size.height) {
distance=fromVC.view.frame.size.width-_cellRect.origin.x;
radius=distance>_cellRect.origin.x?distance:_cellRect.origin.x+88;
}else{
distance=fromVC.view.frame.size.height-_cellRect.origin.y;
radius=distance>_cellRect.origin.y?distance:_cellRect.origin.y+88;
}
radius=radius*2;
UIBezierPath *finalPath=[UIBezierPath bezierPathWithOvalInRect:CGRectInset(_cellRect,
- radius,
- radius)];
_initaialPath=initailPath;
_finalPath=finalPath;
//Create a Layer Mask
_maskLayer=[[CAShapeLayer alloc] init];
_maskLayer.path=finalPath.CGPath;
toVC.view.layer.mask=_maskLayer;
[self animateLayer:_maskLayer withCompletion:^{
BOOL isComple=![transitionContext transitionWasCancelled];
if (!isComple) {
[containerView addSubview:fromVC.view];
[toVC.view removeFromSuperview];
}
[transitionContext completeTransition:isComple];
}];
}
-(void)startInteractiveTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext{
_transitionContext=transitionContext;
[self animateTransition:transitionContext];
[self pauseTime:[_transitionContext containerView].layer];
}
This is the main animation,it work perfectly without interactive. Then i tried to control it with these code:
-(void)updateInteractiveTransition:(CGFloat)percentComplete{
[_transitionContext updateInteractiveTransition:percentComplete];
[_transitionContext containerView].layer.timeOffset=_pausedTime + [self transitionDuration:_transitionContext]*percentComplete;
}
-(void)finishInteractiveTransition{
[_transitionContext finishInteractiveTransition];
[self resumeTime:[_transitionContext containerView].layer];
}
These two functions work perfectly
Buthere is the Problem with "Cancel Transition" When i cancel the transition it disappear suddenly (I have tried with the solution in this question But That's not work for me) here is now my code:
- (void)cancelInteractiveTransition {
//Must Cancel System InteractiveTransition FRIST
[_transitionContext cancelInteractiveTransition];
//Then adjust the layer time
CALayer *maskLayer =[_transitionContext containerView].layer;
maskLayer.beginTime = CACurrentMediaTime();
//MOST IMPORTANT
[UIView animateWithDuration:0.5 animations:^{
maskLayer.timeOffset=0.0;
} completion:^(BOOL finished) {
[[_transitionContext containerView ] addSubview:_fromVC.view];
[_toVC.view removeFromSuperview];
}];
}
Now I almost spend whole week on this, If you can help me I really predicate that.