自定义实现与系统相同的present动画

2021-06-29  本文已影响0人  统领三界
import UIKit

class CustomModalTrans: NSObject,UIViewControllerTransitioningDelegate,
                        UIViewControllerAnimatedTransitioning {
    var isPop:Bool = true
    var temPage:UIViewController?
    var scale:CGFloat = 0.9
    
  
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        2
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        
        if isPop {
            let fromPage = transitionContext.viewController(forKey: .from)
            temPage = fromPage
            let toView = transitionContext.view(forKey: .to)
            let contentView = transitionContext.containerView
            
            contentView.addSubview(toView!)
            let w = contentView.frame.size.width
            let h = contentView.frame.size.height
            toView?.frame = .init(origin: CGPoint.init(x: 0, y: h), size: CGSize.init(width: w, height: h))
            
            UIView.animate(withDuration: 0.5) {
                fromPage?.view.transform = CGAffineTransform.init(scaleX: 0.9, y: 0.9)
                fromPage?.view.layer.masksToBounds = true
                fromPage?.view.layer.cornerRadius = 15
                toView?.transform = CGAffineTransform.init(translationX: 0, y: -h)
                
                toView?.layer.masksToBounds = true
                toView?.layer.cornerRadius = 8
            } completion: { (finish) in
                transitionContext.completeTransition(true)
            }
        } else {
            let fromVC = transitionContext.viewController(forKey: .from)
            let toVC = transitionContext.viewController(forKey: .to)
            
            
            
            UIView.animate(withDuration: 0.5) {
                fromVC?.view.transform = CGAffineTransform.identity
                toVC?.view.transform = CGAffineTransform.identity
            } completion: { (finish) in
                fromVC?.view.removeFromSuperview()
                transitionContext.completeTransition(true)
            }
        }
    }
    
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        isPop = true
        return self
    }

    
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?{
        isPop = false
        return self
    }
    
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        let presentC = YBPresentPage.init(presentedViewController: presented, presentingViewController: presenting) { ytrans in
            let newScale = 0.9 + 0.1 * ytrans
            self.temPage?.view.transform = CGAffineTransform.init(scaleX: newScale, y: newScale)
        }
        
        return presentC
    }
}

import UIKit

class YBPresentPage: UIPresentationController {
    
    var transHandles:((CGFloat)->())?
    

    
    lazy var cover:UIView = {
        let view = UIView.init(frame: UIScreen.main.bounds)
        view.backgroundColor = .clear
        
        return view
    }()
    
    
    init(presentedViewController: UIViewController, presentingViewController: UIViewController?,transHandle:((CGFloat)->())? = nil) {
        self.transHandles = transHandle
        super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
    }
    
    override func containerViewWillLayoutSubviews() {
        super.containerViewWillLayoutSubviews()
//        presentedView?.backgroundColor = .clear
        presentedView?.insertSubview(cover, at: 0)

        
        let w = containerView?.frame.size.width ?? 0
        let h = containerView?.frame.size.height ?? 0

        presentedView?.frame = .init(x: 0, y: 50, width: w, height: h-50)
        
        let pan = UIPanGestureRecognizer.init(target: self, action: #selector(panfunc(sender:)))
        
        presentedView?.addGestureRecognizer(pan)
    }
    
    
    @objc func panfunc(sender:UIPanGestureRecognizer) {
        
        let maxT:CGFloat = 400
        let t = sender.translation(in: presentedView)
        
        containerView?.transform = CGAffineTransform.init(translationX: 0, y: t.y)
        self.transHandles!(t.y/maxT)
        
        switch sender.state {
        case .ended:
            UIView.animate(withDuration: 0.2) {
                if t.y < maxT {
                    self.containerView?.transform = CGAffineTransform.identity
                    self.transHandles!(0)
                } else {
                    self.presentedViewController.dismiss(animated: true, completion: nil)
                }
            } completion: { (finish) in
                
            }
            
        default:
            print("begin")
        }
    }
    
    deinit {
        print("custom present page deinit")
    }
}
上一篇下一篇

猜你喜欢

热点阅读