PinchInteractiveAnimator.swift 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //
  2. // Created by Jake Lin on 4/26/16.
  3. // Copyright © 2016 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public class PinchInteractiveAnimator: InteractiveAnimator {
  7. fileprivate var startScale: CGFloat = 0
  8. override func makeGestureRecognizer() -> UIGestureRecognizer {
  9. let gestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handleGesture(for:)))
  10. return gestureRecognizer
  11. }
  12. override func shouldBeginProgress(for gestureRecognizer: UIGestureRecognizer) -> Bool {
  13. guard let gestureRecognizer = gestureRecognizer as? UIPinchGestureRecognizer else {
  14. return false
  15. }
  16. switch interactiveGestureType {
  17. case let .pinch(direction):
  18. switch direction {
  19. case .close:
  20. return gestureRecognizer.velocity < 0
  21. case .open:
  22. return gestureRecognizer.velocity > 0
  23. default:
  24. return true
  25. }
  26. default:
  27. return false
  28. }
  29. }
  30. override func calculateProgress(for gestureRecognizer: UIGestureRecognizer) -> (progress: CGFloat, shouldFinishInteractiveTransition: Bool) {
  31. guard let gestureRecognizer = gestureRecognizer as? UIPinchGestureRecognizer,
  32. gestureRecognizer.view?.superview != nil else {
  33. return (0, false)
  34. }
  35. if gestureRecognizer.state == .began {
  36. startScale = gestureRecognizer.scale
  37. }
  38. var progress: CGFloat
  39. switch interactiveGestureType {
  40. case let .pinch(direction):
  41. switch direction {
  42. case .close:
  43. progress = 1.0 - gestureRecognizer.scale / startScale
  44. case .open:
  45. let scaleFator: CGFloat = 1.2 // To make the pinch open gesture more natural 😓
  46. progress = gestureRecognizer.scale / scaleFator - 1.0
  47. default:
  48. // For both `.Close` and `.Open`
  49. progress = abs(1.0 - gestureRecognizer.scale / startScale)
  50. }
  51. default:
  52. return (0, false)
  53. }
  54. progress = min(max(progress, 0), 0.99)
  55. // Finish the transition when pass the threathold
  56. let shouldFinishInteractiveTransition = progress > 0.5
  57. return (progress, shouldFinishInteractiveTransition)
  58. }
  59. }