美文网首页
iOS 自定义VC切换动画

iOS 自定义VC切换动画

作者: 圆木鱼 | 来源:发表于2016-10-24 17:30 被阅读0次

    在有些情况下,系统自带的导航的push动画无法满足我们APP的设计需求,我们需要自定义VC的转场动画,下面是我参照别人博客,写的一个一个自定义转场动画.

    (一) push
    这里有一个push的自定义动画:

    -(void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
        self.navigationController.delegate = self;
    }
    
    -(void)viewWillDisappear:(BOOL)animated{
        [super viewWillDisappear:animated];
        if (self.navigationController.delegate == self) {
            self.navigationController.delegate = nil;
        }
    }
    
    - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                      animationControllerForOperation:(UINavigationControllerOperation)operation
                                                   fromViewController:(UIViewController *)fromVC
                                                     toViewController:(UIViewController *)toVC {
        if (fromVC == self && [toVC isKindOfClass:[SecondViewController class]]) {
            return [[FirstTransition alloc] init];
        }
        else {
            return nil;
        }
    }
    

    这里需要实现导航的代理,实现导航的代理方法.其中,

    FirstTransition 
    

    是自己定义的一个动画效果,具体代码如下:

    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
        return 0.5;
    }
    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
        
        FirstViewController *fromViewController = (FirstViewController*)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        SecondViewController *toViewController = (SecondViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        
        UIView *containerView = [transitionContext containerView];
        NSTimeInterval duration = [self transitionDuration:transitionContext];
        
        //设置初始view的状态
        NSLog(@"frame = %@",NSStringFromCGRect([transitionContext finalFrameForViewController:toViewController]));
        toViewController.view.frame = CGRectMake(0, 667, 375, 667);
        
        [containerView addSubview:toViewController.view];
        
        [UIView animateWithDuration:duration animations:^{
            toViewController.view.frame = CGRectMake(0, 0, 375, 667);
            fromViewController.view.frame = CGRectMake(0, -667, 375, 667);
        }completion:^(BOOL finished) {
            
            [transitionContext completeTransition:!transitionContext.transitionWasCancelled];
        }];
    }
    

    其中,

        UIView *containerView = [transitionContext containerView];
    

    类似动画的画布,这里可以处理我们需要设置的一些坐标类等参数.这里我做的是一个向上推出的动画效果.

    (二) pop
    同样的,先上代码:

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        self.navigationController.delegate = self;
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        if (self.navigationController.delegate == self) {
            self.navigationController.delegate = nil;
        }
    }
    
    -(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
        if (fromVC == self && [toVC isKindOfClass:[FirstViewController class]]) {
            return [[SecondTransition alloc] init];
        }
        return nil;
    }
    
    -(id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController{
        if ([animationController isKindOfClass:[SecondTransition class]]) {
            return self.interactivePopTransition;
        }
        return nil;
    }
    
    -(void)handlePopRecognizer:(UIScreenEdgePanGestureRecognizer*)recognizer{
        //计算用户拖动距离
        CGFloat progress = [recognizer translationInView:self.view].x / (self.view.bounds.size.width * 1.0);
        progress = MIN(1.0, MAX(0.0, progress));
        
        if (recognizer.state == UIGestureRecognizerStateBegan) {
            self.interactivePopTransition = [[UIPercentDrivenInteractiveTransition alloc] init];
            [self.navigationController popViewControllerAnimated:YES];
        }
        else if(recognizer.state == UIGestureRecognizerStateChanged){
            [self.interactivePopTransition updateInteractiveTransition:progress];
        }
        else if(recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled){
            if (progress > 0.5) {
                [self.interactivePopTransition finishInteractiveTransition];
            }else{
                [self.interactivePopTransition cancelInteractiveTransition];
            }
            
            self.interactivePopTransition = nil;
        }
    }
    

    这里的 self.interactivePopTransition的是UIPercentDrivenInteractiveTransition的实例,关于UIPercentDrivenInteractiveTransition,这里有篇详细介绍:
    https://onevcat.com/2013/10/vc-transition-in-ios7/
    这样可以根据手势来控制动画的进行程度,因为这里我写的是与pop相反的动画效果.

    SecondTransition
    

    里面的代码如下:

    
    -(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
        return 0.3;
    }
    
    -(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
        // 获取两个互相切换的VC
        SecondViewController *fromViewController = (SecondViewController*)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        FirstViewController *toViewController = (FirstViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        // 获得画布及动画时间
        UIView *containerView = [transitionContext containerView];
        NSTimeInterval duration = [self transitionDuration:transitionContext];
        //设置初始view的状态
        [containerView insertSubview:toViewController.view belowSubview:fromViewController.view];
        [UIView animateWithDuration:duration animations:^{
            fromViewController.view.alpha = 1.0;
            toViewController.view.frame = CGRectMake(0, 0, 375, 667);
            fromViewController.view.frame = CGRectMake(0, 667, 375, 667);
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:!transitionContext.transitionWasCancelled];
        }];
    }
    

    对应的手势为:

        UIScreenEdgePanGestureRecognizer *popRegognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePopRecognizer:)];
        popRegognizer.edges = UIRectEdgeLeft;
        [self.view addGestureRecognizer:popRegognizer];
    
    

    以上代码均来自他人博客,只有动画是我自己写到的,只为自己查询方便,见谅.

    相关文章

      网友评论

          本文标题:iOS 自定义VC切换动画

          本文链接:https://www.haomeiwen.com/subject/xgdluttx.html