SlideAnimator.swift 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // Created by Tom Baranes on 08/05/16.
  3. // Copyright © 2016 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public class SlideAnimator: NSObject, AnimatedTransitioning {
  7. // MARK: - AnimatorProtocol
  8. public var transitionAnimationType: TransitionAnimationType
  9. public var transitionDuration: Duration = defaultTransitionDuration
  10. public var reverseAnimationType: TransitionAnimationType?
  11. public var interactiveGestureType: InteractiveGestureType?
  12. // MARK: - private
  13. fileprivate var fromDirection: TransitionAnimationType.Direction
  14. fileprivate var isHorizontal = false
  15. fileprivate var isReverse = false
  16. fileprivate var isFade = false
  17. public init(from direction: TransitionAnimationType.Direction, isFade: Bool, duration: Duration) {
  18. fromDirection = direction
  19. transitionDuration = duration
  20. self.isFade = isFade
  21. isHorizontal = fromDirection.isHorizontal
  22. transitionAnimationType = .slide(to: direction, isFade: isFade)
  23. reverseAnimationType = .slide(to: direction.opposite, isFade: isFade)
  24. interactiveGestureType = .pan(from: direction.matchingGesture)
  25. isReverse = direction == .right || direction == .bottom
  26. super.init()
  27. }
  28. }
  29. extension SlideAnimator: UIViewControllerAnimatedTransitioning {
  30. public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
  31. return retrieveTransitionDuration(transitionContext: transitionContext)
  32. }
  33. public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  34. let (tempfromView, tempToView, tempContainerView) = retrieveViews(transitionContext: transitionContext)
  35. guard let fromView = tempfromView, let toView = tempToView, let containerView = tempContainerView else {
  36. transitionContext.completeTransition(true)
  37. return
  38. }
  39. let travelDistance = isHorizontal ? containerView.bounds.width : containerView.bounds.height
  40. let travel = CGAffineTransform(translationX: isHorizontal ? (isReverse ? travelDistance : -travelDistance) : 0,
  41. y: isHorizontal ? 0 : (isReverse ? travelDistance : -travelDistance))
  42. containerView.addSubview(toView)
  43. if isFade {
  44. toView.alpha = 0
  45. }
  46. toView.transform = travel.inverted()
  47. animateSlideTransition(toView: toView, fromView: fromView, travel: travel) {
  48. toView.transform = .identity
  49. fromView.transform = .identity
  50. transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
  51. }
  52. }
  53. }
  54. // MARK: - Animation
  55. private extension SlideAnimator {
  56. func animateSlideTransition(toView: UIView, fromView: UIView, travel: CGAffineTransform, completion: @escaping AnimatableCompletion) {
  57. UIView.animate(withDuration: transitionDuration, animations: {
  58. fromView.transform = travel
  59. toView.transform = .identity
  60. if self.isFade {
  61. fromView.alpha = 0
  62. toView.alpha = 1
  63. }
  64. },
  65. completion: { _ in
  66. completion()
  67. })
  68. }
  69. }