自定义实现与系统相同的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")
}
}