ios框架iOS Developer我的ios进阶

接上一篇自定义转场动画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;
}
上一篇下一篇

猜你喜欢

热点阅读