ios present 转场动画

43 阅读1分钟
1.设置transitioningDelegate,modalPresentationStyle
let presentTransitionDelegate = SDEModalTransitionDelegate()
let toVC = segue.destination as! PresentedViewController

/// 设置 transitioningDelegate
toVC.transitioningDelegate = presentTransitionDelegate

toVC.modalPresentationStyle = .custom
2.实现transitioningDelegate
class SDEModalTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        return OverlayAnimationController()
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        return OverlayAnimationController()

    }

///  presentationController 定制 presentedView 的外观:设定 presentedView 的尺寸以及在 containerView 中添加自定义视图并为这些视图添加动画
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {

        return OverlayPresentationController(presentedViewController: presented, presenting: presenting)

    }

}
3.实现OverlayAnimationController:UIViewControllerAnimatedTransitioning
class OverlayAnimationController: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {

        return 0.3

    }

  


    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        let containerView = transitionContext.containerView

        guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else {

            return

        }

  


        let fromView = fromVC.view

        let toView = toVC.view

        let duration = self.transitionDuration(using: transitionContext)

  


        if toVC.isBeingPresented {

            containerView.addSubview(toView!)

            /*

            let toViewWidth = containerView.frame.width * 2 / 3, toViewHeight = containerView.frame.height * 2 / 3

            toView?.center = containerView.center

            toView?.bounds = CGRect(x: 0, y: 0, width: 1, height: 1)//toViewHeight

            */

  


            toView?.alpha  = 0

            //.curveEaseInOut

            UIView.animate(withDuration: duration, delay: 0, options: [], animations: {

                /*

                toView?.bounds = CGRect(x: 0, y: 0, width: toViewWidth, height: toViewHeight)

                */

                toView?.alpha = 1

            }, completion: { _ in

                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)

            })

        }

        // Dismissal 转场中不要将 toView 添加到 containerView

        if fromVC.isBeingDismissed {

            let fromViewHeight = fromView?.frame.height

            UIView.animate(withDuration: duration, animations: {

//                fromView?.bounds = CGRect(x: 0, y: 0, width: 1, height: fromViewHeight!)

                fromView?.alpha = 0

            }, completion: { _ in

                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)

            })

        }

    }

}
4.presentationController 定制 presentedView 的外观:设定 presentedView 的尺寸以及在 containerView 中添加自定义视图并为这些视图添加动画

OverlayPresentationController

class OverlayPresentationController: UIPresentationController {

    let dimmingView = UIView()

    

    override func presentationTransitionWillBegin() {

        containerView?.addSubview(dimmingView)

        

        let dimmingViewInitailWidth = containerView!.frame.width * 2 / 3, dimmingViewInitailHeight = containerView!.frame.height * 2 / 3

        dimmingView.backgroundColor = UIColor(white: 0.0, alpha: 0.5)

        dimmingView.center = containerView!.center

        dimmingView.bounds = CGRect(x: 0, y: 0, width: dimmingViewInitailWidth , height: dimmingViewInitailHeight)

        

        _ = presentedViewController.transitionCoordinator?.animate(alongsideTransition: {

            _ in

            self.dimmingView.bounds = self.containerView!.bounds

            }, completion: nil)

    }

    

    override func dismissalTransitionWillBegin() {

        _ = presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in

            self.dimmingView.alpha = 0.0

            }, completion: nil)

    }

    

    override func containerViewWillLayoutSubviews(){

        dimmingView.center = containerView!.center

        dimmingView.bounds = containerView!.bounds

        

        let width = containerView!.frame.width * 2 / 3, height = containerView!.frame.height * 2 / 3

        presentedView?.center = containerView!.center

        presentedView?.bounds = CGRect(x: 0, y: 0, width: width, height: height)

    }

}

参考:blog.devtang.com/2016/03/13/… 参考demo:github.com/seedante/iO… 参考:www.jianshu.com/p/96af57be1…