iOS 自定义转场动画

2021-12-22  本文已影响0人  前行的骆驼

iOS内部提供了自定义转场动画的代理

@property (nullable, nonatomic, weak) id <UIViewControllerTransitioningDelegate> transitioningDelegate;

我们可以在UIViewController直接写转场动画,也可以新建一个类写转场动画,首先我们要给要跳转的UIViewController设置transitioningDelegate

- (instancetype)init  {

    self = [super init];

    if (self)  { 

        self.transitioningDelegate = self;

    }

        return self;  

}

然后实现几个代理方法

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return self;

}

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {

    return self;

}

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {

    return 0.3;//这里设置动画时长

}

//所有的过渡动画事务都在这个方法里面完成

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{

    //取出转场前后的视图控制器

    UIViewController * fromVC = (UIViewController *)[transitionContext  viewControllerForKey:UITransitionContextFromViewControllerKey];

    UIViewController * toVC = (UIViewController *)[transitionContext  viewControllerForKey:UITransitionContextToViewControllerKey];

    //取出转场前后视图控制器上的视图view

    UIView* toView = [transitionContext viewForKey:UITransitionContextToViewKey]?:toVC.view;

    UIView* fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]?:fromVC.view;

    //这里有个重要的概念containerView,containerView作为要present的view的控制view,要present的view的所有动画都是在containerView上执行的,这里模仿一个类似京东的加入购物车弹出选择规格动画

    UIView*containerView = [transitionContext containerView]; 

//这里判断toView是否是要present的view,如果是,那么是在做present动画,如果不是,那么是在执行dismiss动画

//这里要特别说明,动画执行完成时,要调用 [transitionContext completeTransition:YES];这是在通知系统动画完成了,如果没有这一句,那么相当于转场动画没执行完成,导致页面无法点击,如果在执行了这一句代码时,,,继续对页面进行动画,会导致动画失效

    if(toView == self.view) {

        toView.frame = containerView.bounds;

        [containerView addSubview:toView];

        CATransform3D transform = CATransform3DIdentity;

        transform.m34 = -1/1000;

        transform = CATransform3DRotate(transform,M_PI/16,1,0,0);

        transform = CATransform3DTranslate(transform,0,0, -100);

        transform = CATransform3DScale(transform,0.96,0.96,1);

        [UIView animateWithDuration:0.5 animations:^{

            fromView.layer.transform= transform;

        }completion:^(BOOLfinished) {

            [transitionContext completeTransition:YES];

        }];

    }else{

        [UIView animateWithDuration:0.3 animations:^{

            toView.layer.transform = CATransform3DMakeScale(1, 1, 1);

        } completion:^(BOOL finished) {

            [fromView removeFromSuperview];

            [transitionContext completeTransition:YES];

        }];

    }

}

上一篇下一篇

猜你喜欢

热点阅读