ios-自定义转场动画基础

在开发当中其实我们除了push视图从右往左进来,modal是从下往上进来,我们还可以自定义转场动画,目前学习的比较浅,稍微记录下。

首先,之前我们modal一个控制器的时候可能是直接这么做的,这么做的话,原来的控制器其实会被暂时的移出屏幕,尽管我们dismiss的时候,可能就看到原来的控制器是在下面的,但其实这是个假象

比如说下面是modal一个控制器

let vc = UIViewController()

self?.present(vc, animated: true, completion: nil)
        }

如果我们想自定义转场动画的话,我们首先要设置modal出来的是自定义转场,这样做了之后,原来的控制器就会在下面了。其他的没有区别

vc.modalPresentationStyle = .custom


如果我们一旦设置了动画的代理,也就是说设置了由谁来提供动画。其中pictureBrowerAnimator是我们自定义的提供动画转场的对象

vc.transitioningDelegate = self?.pictureBrowserAnimator

注意这个对象需要遵守UIViewControllerTransitioningDelegate协议,有两个代理方法是需要实现的,就是返回提供展现动画的对象是谁,以及提供解除动画的对象是谁。

//返回提供展现动画的对象
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        

       return self
    }
    //返回提供解除动画的对象
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
       
        return self
    }

返回的这个对象必须遵守UIViewControllerAnimatedTransitioning协议

我们需要去设置这个转场动画执行的时间

//设置动画时长
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {

        return 1
    }

///实现具体的动画效果,所有的过渡动画事务都在这个方法里面完成
    ///一旦我们实现了这个方法,所有的动画代码都交给程序员来管理,系统的动画就没有效果了
    ///转场动画的上下文transitionContext 提供动画需要的素材
    /**
        1、这个动画上下文中素材包括容器视图,会将modal要展现的视图包装到容器视图当中,我需要自己去指定视图的大小
        2、我们可以通过UITransitionContextViewControllerKey.from,获取来源控制器.toVCmodal获取目标控制器
        3、viewForKey也分为fromView和toView,以便我们获取来源视图和目标视图,Custom 模式下,presentingView 并不受 containerView 管理,
        这时通过viewForKey:方法来获取 presentingView 得到的是 nil
        4、completeTransition就是无论转场是否被取消,都必须去调用,否则系统不会做其他事情
     */
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {


       //来源控制器
       let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
       //目标控制器
       let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
        //获得modal要展现的控制器的根视图
       let toView = transitionContext?.view(forKey: UITransitionContextViewKey.to)
        //获得modal的来源控制器的根视图
        let fromView = transitionContext?.view(forKey: UITransitionContextViewKey.from)
        //告诉系统转场动画已经完成
            transitionContext?.completeTransition(true)

    }

我们如果需要自己去实现转场动画的话,可以自己去写方法,然后在func animateTransition(using transitionContext: UIViewControllerContextTransitioning)中可以进行调用,就比如说我们写了一个modal出来展示的动画。

 private func presentAnimator(transitionContext: UIViewControllerContextTransitioning?)
    {
       //获得modal要展现的控制器的根视图
       let toView = transitionContext?.view(forKey: UITransitionContextViewKey.to)
        //将视图添加到容器中
        transitionContext?.containerView.addSubview(toView!)

        toView?.alpha = 0
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toView?.alpha = 1
        }) { (_) in

            //告诉系统转场动画已经完成
            transitionContext?.completeTransition(true)
        }
    }
dismiss的动画

//解除视图的转场动画
    private func dismissAnimator(transitionContext: UIViewControllerContextTransitioning?)
    {
        //获取视图
         let fromView = transitionContext?.view(forKey: UITransitionContextViewKey.from)

        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {

            fromView?.alpha = 0
        }) { (_) in

            //将视图移走
            fromView?.removeFromSuperview()
            //告诉系统动画已经做完了
            transitionContext?.completeTransition(true)
        }

    }







你可能感兴趣的:(ios-Swift)