SWIFT3.0自定义转场动画

。_饼干妹妹 提交于 2020-02-25 12:20:50

SWIFT3.0自定义转场动画

//1.创建弹出的控制器

let popooverVc = PopoverViewController()
        //2.设置控制器的modal样式
        popooverVc.modalPresentationStyle = .custom
        //3.设置转场的代理
        popooverVc.transitioningDelegate = popoverAnimator
        popoverAnimator.presentedFrame = CGRect(x: 100, y: 55, width: 180, height: 250)
        //4.弹出控制器
        present(popooverVc, animated: true, completion: nil)

2.设置弹出视图尺寸相关

class ADPresentationController: UIPresentationController {
    //对外提供属性用以设置弹出控制视图的尺寸
    var presentedFrame : CGRect = CGRect.zero
    //蒙板view
    fileprivate lazy var coverView : UIView = UIView()
    
    //MARK: - 系统回调函数
    override func containerViewWillLayoutSubviews() {
        super.containerViewDidLayoutSubviews()
        
        //设置弹出View的尺寸
        presentedView?.frame = presentedFrame
        
        //添加蒙板
        setupCoverView()
    }
}

//MARK: - 设置UI界面相关
extension ADPresentationController {
    
    fileprivate func setupCoverView() {
        
        //添加蒙板
        containerView?.insertSubview(coverView, at: 0)
        coverView.backgroundColor = UIColor(white: 0.2, alpha: 0.5)
        coverView.frame = containerView!.bounds
        
        //添加手势
        let tabGes = UITapGestureRecognizer(target: self, action: #selector(ADPresentationController.tapgestureAction))
        coverView.addGestureRecognizer(tabGes)
    }
}

//MARK: - 监控事件
extension ADPresentationController {
    
    
    @objc fileprivate func tapgestureAction() {
        presentedViewController.dismiss(animated: true, completion: nil)
    }
}

3.设置动画相关

import UIKit

class PopoverAnimator: NSObject {

    // MARK:- 对外提供的属性
    var isPresented : Bool = false
    var presentedFrame : CGRect = CGRect.zero
    
    var callBack : ((_ presented : Bool) -> ())?
    
    // MARK:- 自定义构造函数
    // 注意:如果自定义了一个构造函数,但是没有对默认构造函数init()进行重写,那么自定义的构造函数会覆盖默认的init()构造函数
    init(callBack : @escaping (_ presented : Bool) -> ()) {
        self.callBack = callBack
    }
    override init() {
        
    }
    
}


//MARK: - 自定义转场代理方法
extension PopoverAnimator : UIViewControllerTransitioningDelegate {
    
    // 目的:改变弹出View的尺寸
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        
        let presentation = ADPresentationController(presentedViewController: presented, presenting: presenting)
        presentation.presentedFrame = presentedFrame
        return presentation
    }
    
    //目的:自定义弹出动画
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        isPresented = true
        callBack!(isPresented)
        return self
    }
    
    //目的:自定义消失出动画
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        isPresented = false
         callBack!(isPresented)
        return self
    }
    
}

//MARK: - 弹出和消失的动画方法
extension PopoverAnimator : UIViewControllerAnimatedTransitioning {
    //设置动画执行的时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        
        return 0.5
    }
    
    //获取转场动画的上下文
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        
        isPresented ? animationForPresentedView(transitionContext) : animationForDismissedView(transitionContext)
    }
    
    ///自定义弹出动画
    fileprivate func animationForPresentedView(_ transitionContext: UIViewControllerContextTransitioning) {
        //获取弹出的View
        let presentedView = transitionContext.view(forKey: UITransitionContextViewKey.to)!
        //将弹出的View加到containerView中
        transitionContext.containerView.addSubview(presentedView)
        //执行动画
        presentedView.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
        presentedView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: { () -> Void in
            presentedView.transform = CGAffineTransform.identity
        }, completion: { (_) -> Void in
            //必须告诉转场上下文你已经完成动画
            transitionContext.completeTransition(true)
        })
    }
    
    //消失动画
    fileprivate func animationForDismissedView(_ transitionContex: UIViewControllerContextTransitioning) {
        //获取消失的View
        let dismissView = transitionContex.view(forKey: UITransitionContextViewKey.from)
        //执行动画
        UIView.animate(withDuration: transitionDuration(using: transitionContex), animations: { () -> Void in
            dismissView?.transform = CGAffineTransform(scaleX: 0.0001, y: 0.0001)
            }, completion: { (_) -> Void in
              dismissView?.removeFromSuperview()
            //必须告诉转场上下文你已经完成动画
                transitionContex.completeTransition(true)
        })
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!