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.