我想用 UIViewAnimation 构建交互式过渡。但是我可以为它设置动画的图层属性很少。所以我决定使用 CAAnimation。我想更改 ViewController 的视图掩码,这是代码
-(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];
}
这是主要动画,无需交互即可完美运行。然后我尝试用这些代码控制它:
-(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];
}
这两个功能完美运行
但这是“取消转换”的问题 当我取消转换时它突然消失(我已经尝试过这个问题中的解决方案但这对我不起作用)现在是我的代码:
- (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];
}];
}
现在我几乎花了整整一个星期的时间,如果你能帮助我,我真的断言。