ScreenEdgePanInteractiveAnimator.swift 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //
  2. // Created by Jake Lin on 4/5/16.
  3. // Copyright © 2016 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public class ScreenEdgePanInteractiveAnimator: InteractiveAnimator {
  7. override func makeGestureRecognizer() -> UIGestureRecognizer {
  8. let gestureRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handleGesture(for:)))
  9. switch interactiveGestureType {
  10. case let .screenEdgePan(direction):
  11. switch direction {
  12. case .left:
  13. gestureRecognizer.edges = .left
  14. case .right:
  15. gestureRecognizer.edges = .right
  16. case .horizontal:
  17. gestureRecognizer.edges = [.left, .right]
  18. case .top:
  19. gestureRecognizer.edges = .top
  20. case .bottom:
  21. gestureRecognizer.edges = .bottom
  22. case .vertical:
  23. gestureRecognizer.edges = [.top, .bottom]
  24. default:
  25. break
  26. }
  27. default:
  28. break
  29. }
  30. return gestureRecognizer
  31. }
  32. override func calculateProgress(for gestureRecognizer: UIGestureRecognizer) -> (progress: CGFloat, shouldFinishInteractiveTransition: Bool) {
  33. guard let gestureRecognizer = gestureRecognizer as? UIScreenEdgePanGestureRecognizer,
  34. let superview = gestureRecognizer.view?.superview else {
  35. return (0, false)
  36. }
  37. let translation = gestureRecognizer.translation(in: superview)
  38. let velocity = gestureRecognizer.velocity(in: superview)
  39. var progress: CGFloat
  40. let distance: CGFloat
  41. let speed: CGFloat
  42. switch interactiveGestureType {
  43. case let .screenEdgePan(direction):
  44. switch direction {
  45. case .horizontal:
  46. distance = superview.frame.width
  47. progress = abs(translation.x / distance)
  48. speed = abs(velocity.x)
  49. case .left:
  50. distance = superview.frame.width
  51. progress = translation.x / distance
  52. speed = velocity.x
  53. case .right:
  54. distance = superview.frame.width
  55. progress = -(translation.x / distance)
  56. speed = -velocity.x
  57. case .vertical:
  58. distance = superview.frame.height
  59. progress = abs(translation.y / distance)
  60. speed = abs(velocity.y)
  61. case .top:
  62. distance = superview.frame.height
  63. progress = translation.y / distance
  64. speed = velocity.y
  65. case .bottom:
  66. distance = superview.frame.height
  67. progress = -translation.y / distance
  68. speed = -velocity.y
  69. default:
  70. return (0, false)
  71. }
  72. default:
  73. return (0, false)
  74. }
  75. progress = min(max(progress, 0), 0.99)
  76. // Finish the transition when pass the threathold
  77. let shouldFinishInteractiveTransition = progress > 0.5 || speed > 1000
  78. return (progress, shouldFinishInteractiveTransition)
  79. }
  80. }