|
@@ -1,164 +0,0 @@
|
|
|
-
|
|
|
-
|
|
|
-import UIKit
|
|
|
-
|
|
|
-class ZoomDismissalInteractionController: NSObject {
|
|
|
-
|
|
|
- var transitionContext: UIViewControllerContextTransitioning?
|
|
|
- var animator: UIViewControllerAnimatedTransitioning?
|
|
|
-
|
|
|
- var fromReferenceImageViewFrame: CGRect?
|
|
|
- var toReferenceImageViewFrame: CGRect?
|
|
|
-
|
|
|
- func didPanWith(gestureRecognizer: UIPanGestureRecognizer) {
|
|
|
-
|
|
|
- guard let transitionContext = self.transitionContext,
|
|
|
- let animator = self.animator as? ZoomAnimator,
|
|
|
- let transitionImageView = animator.transitionImageView,
|
|
|
- let fromVC = transitionContext.viewController(forKey: .from),
|
|
|
- let toVC = transitionContext.viewController(forKey: .to),
|
|
|
- let fromReferenceImageView = animator.fromDelegate?.referenceImageView(for: animator),
|
|
|
- let toReferenceImageView = animator.toDelegate?.referenceImageView(for: animator),
|
|
|
- let fromReferenceImageViewFrame = self.fromReferenceImageViewFrame,
|
|
|
- let toReferenceImageViewFrame = self.toReferenceImageViewFrame else {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- fromReferenceImageView.isHidden = true
|
|
|
-
|
|
|
- let anchorPoint = CGPoint(x: fromReferenceImageViewFrame.midX, y: fromReferenceImageViewFrame.midY)
|
|
|
- let translatedPoint = gestureRecognizer.translation(in: fromReferenceImageView)
|
|
|
- let verticalDelta : CGFloat = translatedPoint.y < 0 ? 0 : translatedPoint.y
|
|
|
-
|
|
|
- let backgroundAlpha = backgroundAlphaFor(view: fromVC.view, withPanningVerticalDelta: verticalDelta)
|
|
|
- let scale = scaleFor(view: fromVC.view, withPanningVerticalDelta: verticalDelta)
|
|
|
-
|
|
|
- fromVC.view.alpha = backgroundAlpha
|
|
|
-
|
|
|
- transitionImageView.transform = CGAffineTransform(scaleX: scale, y: scale)
|
|
|
- let newCenter = CGPoint(x: anchorPoint.x + translatedPoint.x, y: anchorPoint.y + translatedPoint.y - transitionImageView.frame.height * (1 - scale) / 2.0)
|
|
|
- transitionImageView.center = newCenter
|
|
|
-
|
|
|
- toReferenceImageView.isHidden = true
|
|
|
-
|
|
|
- transitionContext.updateInteractiveTransition(1 - scale)
|
|
|
-
|
|
|
- toVC.tabBarController?.tabBar.alpha = 1 - backgroundAlpha
|
|
|
-
|
|
|
- if gestureRecognizer.state == .ended {
|
|
|
-
|
|
|
- let velocity = gestureRecognizer.velocity(in: fromVC.view)
|
|
|
- if velocity.y < 0 || newCenter.y < anchorPoint.y {
|
|
|
-
|
|
|
- //cancel
|
|
|
- UIView.animate(
|
|
|
- withDuration: 0.5,
|
|
|
- delay: 0,
|
|
|
- usingSpringWithDamping: 0.9,
|
|
|
- initialSpringVelocity: 0,
|
|
|
- options: [],
|
|
|
- animations: {
|
|
|
- transitionImageView.frame = fromReferenceImageViewFrame
|
|
|
- fromVC.view.alpha = 1.0
|
|
|
- toVC.tabBarController?.tabBar.alpha = 0
|
|
|
- },
|
|
|
- completion: { completed in
|
|
|
-
|
|
|
- toReferenceImageView.isHidden = false
|
|
|
- fromReferenceImageView.isHidden = false
|
|
|
- transitionImageView.removeFromSuperview()
|
|
|
- animator.transitionImageView = nil
|
|
|
- transitionContext.cancelInteractiveTransition()
|
|
|
- transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
|
|
- animator.toDelegate?.transitionDidEndWith(zoomAnimator: animator)
|
|
|
- animator.fromDelegate?.transitionDidEndWith(zoomAnimator: animator)
|
|
|
- self.transitionContext = nil
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- //start animation
|
|
|
- let finalTransitionSize = toReferenceImageViewFrame
|
|
|
-
|
|
|
- UIView.animate(withDuration: 0.25,
|
|
|
- delay: 0,
|
|
|
- options: [],
|
|
|
- animations: {
|
|
|
- fromVC.view.alpha = 0
|
|
|
- transitionImageView.frame = finalTransitionSize
|
|
|
- toVC.tabBarController?.tabBar.alpha = 1
|
|
|
-
|
|
|
- }, completion: { completed in
|
|
|
-
|
|
|
- transitionImageView.removeFromSuperview()
|
|
|
- toReferenceImageView.isHidden = false
|
|
|
- fromReferenceImageView.isHidden = false
|
|
|
-
|
|
|
- self.transitionContext?.finishInteractiveTransition()
|
|
|
- transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
|
|
- animator.toDelegate?.transitionDidEndWith(zoomAnimator: animator)
|
|
|
- animator.fromDelegate?.transitionDidEndWith(zoomAnimator: animator)
|
|
|
- self.transitionContext = nil
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- func backgroundAlphaFor(view: UIView, withPanningVerticalDelta verticalDelta: CGFloat) -> CGFloat {
|
|
|
- let startingAlpha:CGFloat = 1.0
|
|
|
- let finalAlpha: CGFloat = 0.0
|
|
|
- let totalAvailableAlpha = startingAlpha - finalAlpha
|
|
|
-
|
|
|
- let maximumDelta = view.bounds.height / 4.0
|
|
|
- let deltaAsPercentageOfMaximun = min(abs(verticalDelta) / maximumDelta, 1.0)
|
|
|
-
|
|
|
- return startingAlpha - (deltaAsPercentageOfMaximun * totalAvailableAlpha)
|
|
|
- }
|
|
|
-
|
|
|
- func scaleFor(view: UIView, withPanningVerticalDelta verticalDelta: CGFloat) -> CGFloat {
|
|
|
- let startingScale:CGFloat = 1.0
|
|
|
- let finalScale: CGFloat = 0.5
|
|
|
- let totalAvailableScale = startingScale - finalScale
|
|
|
-
|
|
|
- let maximumDelta = view.bounds.height / 2.0
|
|
|
- let deltaAsPercentageOfMaximun = min(abs(verticalDelta) / maximumDelta, 1.0)
|
|
|
-
|
|
|
- return startingScale - (deltaAsPercentageOfMaximun * totalAvailableScale)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-extension ZoomDismissalInteractionController: UIViewControllerInteractiveTransitioning {
|
|
|
- func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) {
|
|
|
- self.transitionContext = transitionContext
|
|
|
-
|
|
|
- let containerView = transitionContext.containerView
|
|
|
-
|
|
|
- guard let animator = self.animator as? ZoomAnimator,
|
|
|
- let fromVC = transitionContext.viewController(forKey: .from),
|
|
|
- let toVC = transitionContext.viewController(forKey: .to),
|
|
|
- let fromReferenceImageViewFrame = animator.fromDelegate?.referenceImageViewFrameInTransitioningView(for: animator),
|
|
|
- let toReferenceImageViewFrame = animator.toDelegate?.referenceImageViewFrameInTransitioningView(for: animator),
|
|
|
- let fromReferenceImageView = animator.fromDelegate?.referenceImageView(for: animator)
|
|
|
- else {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- animator.fromDelegate?.transitionWillStartWith(zoomAnimator: animator)
|
|
|
- animator.toDelegate?.transitionWillStartWith(zoomAnimator: animator)
|
|
|
-
|
|
|
- self.fromReferenceImageViewFrame = fromReferenceImageViewFrame
|
|
|
- self.toReferenceImageViewFrame = toReferenceImageViewFrame
|
|
|
-
|
|
|
- let referenceImage = fromReferenceImageView.image!
|
|
|
-
|
|
|
- containerView.insertSubview(toVC.view, belowSubview: fromVC.view)
|
|
|
- if animator.transitionImageView == nil {
|
|
|
- let transitionImageView = UIImageView(image: referenceImage)
|
|
|
- transitionImageView.contentMode = .scaleAspectFill
|
|
|
- transitionImageView.clipsToBounds = true
|
|
|
- transitionImageView.frame = fromReferenceImageViewFrame
|
|
|
- animator.transitionImageView = transitionImageView
|
|
|
- containerView.addSubview(transitionImageView)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|