// // SheetContainerPresentationAnimationController.swift // SheetController // // Created by Shadowfacts on 9/24/19. // Copyright © 2019 Shadowfacts. All rights reserved. // import UIKit class SheetContainerPresentationAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat { return 0.25 } else { return 0.5 } } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let toVC = transitionContext.viewController(forKey: .to) as? SheetContainerViewController else { fatalError() } if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat { animateCrossFadeTransition(using: transitionContext) return } toVC.dimmingView.isHidden = true let finalFrame = transitionContext.finalFrame(for: toVC) let dimmingView = UIView(frame: finalFrame) dimmingView.backgroundColor = toVC.dimmingView.backgroundColor dimmingView.alpha = 0 let container = transitionContext.containerView container.addSubview(dimmingView) container.addSubview(toVC.view) let initialConstant = toVC.initialConstant toVC.topConstraint.constant = toVC.view.bounds.height toVC.view.layoutIfNeeded() let duration = transitionDuration(using: transitionContext) let damping = SheetContainerViewController.springDamping let pointsPerSecond: CGFloat = 50 let velocity = pointsPerSecond / initialConstant UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: damping, initialSpringVelocity: velocity, options: []) { // we animate the dimming view's frame so that it doesn't go under the content view, in case there's a transparent background // we also extend the dimming view under any rounded corners the content view has dimmingView.frame = CGRect(x: 0, y: 0, width: dimmingView.bounds.width, height: initialConstant + toVC.content.view.layer.cornerRadius) dimmingView.alpha = toVC.dimmingView.alpha toVC.topConstraint.constant = initialConstant toVC.view.layoutIfNeeded() } completion: { (finished) in dimmingView.removeFromSuperview() toVC.dimmingView.isHidden = false toVC.view.frame = finalFrame transitionContext.completeTransition(!transitionContext.transitionWasCancelled) } } func animateCrossFadeTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let toVC = transitionContext.viewController(forKey: .to) as? SheetContainerViewController else { fatalError() } transitionContext.containerView.addSubview(toVC.view) toVC.view.alpha = 0 let duration = transitionDuration(using: transitionContext) UIView.animate(withDuration: duration) { toVC.view.alpha = 1 } completion: { (finished) in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) } } }