接上一篇自定义转场动画Pop
2016-03-10 本文已影响159人
91阿生
接着上一篇push的自定义转场动画,pop自定义转场其实变得很简单了.
创建类(CustomPopTransition),同样遵守UIViewControllerAnimatedTransitioning.
同样实现这两个方法:
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext;
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext;
代码:
@property (nonatomic, strong) id<UIViewControllerContextTransitioning>customTransitionContext;
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContex{
return 0.5f;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
PopViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
PushViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *contentView = [transitionContext containerView];
UIButton *button = toVC.push;
[contentView addSubview:toVC.view];
[contentView addSubview:fromVC.view];
//绘制大圆
CGSize sideSize = CGSizeMake(button.center.x, toVC.view.frame.size.height - button.center.y);
CGFloat radius = sqrt((sideSize.width * sideSize.width) + (sideSize.height * sideSize.height));
UIBezierPath *startBP = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(button.frame, -radius, -radius)];
//绘制小圆
UIBezierPath *finalBP = [UIBezierPath bezierPathWithOvalInRect:button.frame];
//设置路径
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = finalBP.CGPath;
fromVC.view.layer.mask = maskLayer;
//执行动画
CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
maskLayerAnimation.fromValue = (__bridge id _Nullable)(startBP.CGPath);
maskLayerAnimation.toValue = (__bridge id _Nullable)(finalBP.CGPath);
maskLayerAnimation.duration = [self transitionDuration:transitionContext];
maskLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
maskLayerAnimation.delegate = self;
//添加动画要在最后添加
[maskLayer addAnimation:maskLayerAnimation forKey:@"path"];
}
#######pragma mark - CABasicAnimation代理
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
//告诉系统专场结束
[self.customTransitionContext completeTransition:![self.customTransitionContext transitionWasCancelled]];
//清除fromVC.view和toVC.view上的mask
[self.customTransitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
[self.customTransitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
}
PopViewController.m
同样控制器须遵守<UINavigationControllerDelegate>协议, 所以self.navigationCtroller.delegate = self; //注意设置导航控制器的代理须写在viewWillAppear中或是viewDidAppear.实现导航控制器的代理:
#pragma mark - UINavigationControllerDelegate
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
if (operation == UINavigationControllerOperationPop) {
return self.popAnimation;
}
return nil;
}
#pragma mark - 懒加载
- (CustomPopTransition *)popAnimation{
if (!_popAnimation) {
_popAnimation = [[CustomPopTransition alloc] init];
}
return _popAnimation;
}