SwipeActionTransitioning.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // SwipeActionTransitioning.swift
  3. //
  4. // Created by Jeremy Koch
  5. // Copyright © 2017 Jeremy Koch. All rights reserved.
  6. //
  7. import UIKit
  8. /**
  9. Adopt the `SwipeActionTransitioning` protocol in objects that implement custom appearance of actions during transition.
  10. */
  11. public protocol SwipeActionTransitioning {
  12. /**
  13. Tells the delegate that transition change has occured.
  14. */
  15. func didTransition(with context: SwipeActionTransitioningContext) -> Void
  16. }
  17. /**
  18. The `SwipeActionTransitioningContext` type provides information relevant to a specific action as transitioning occurs.
  19. */
  20. public struct SwipeActionTransitioningContext {
  21. /// The unique action identifier.
  22. public let actionIdentifier: String?
  23. /// The button that is changing.
  24. public let button: UIButton
  25. /// The old visibility percentage between 0.0 and 1.0.
  26. public let newPercentVisible: CGFloat
  27. /// The new visibility percentage between 0.0 and 1.0.
  28. public let oldPercentVisible: CGFloat
  29. internal let wrapperView: UIView
  30. internal init(actionIdentifier: String?, button: UIButton, newPercentVisible: CGFloat, oldPercentVisible: CGFloat, wrapperView: UIView) {
  31. self.actionIdentifier = actionIdentifier
  32. self.button = button
  33. self.newPercentVisible = newPercentVisible
  34. self.oldPercentVisible = oldPercentVisible
  35. self.wrapperView = wrapperView
  36. }
  37. /// Sets the background color behind the action button.
  38. ///
  39. /// - parameter color: The background color.
  40. public func setBackgroundColor(_ color: UIColor?) {
  41. wrapperView.backgroundColor = color
  42. }
  43. }
  44. /**
  45. A scale transition object drives the custom appearance of actions during transition.
  46. As button's percentage visibility crosses the `threshold`, the `ScaleTransition` object will animate from `initialScale` to `identity`. The default settings provide a "pop-like" effect as the buttons are exposed more than 50%.
  47. */
  48. public struct ScaleTransition: SwipeActionTransitioning {
  49. /// Returns a `ScaleTransition` instance with default transition options.
  50. public static var `default`: ScaleTransition { return ScaleTransition() }
  51. /// The duration of the animation.
  52. public let duration: Double
  53. /// The initial scale factor used before the action button percent visible is greater than the threshold.
  54. public let initialScale: CGFloat
  55. /// The percent visible threshold that triggers the scaling animation.
  56. public let threshold: CGFloat
  57. /**
  58. Contructs a new `ScaleTransition` instance.
  59. - parameter duration: The duration of the animation.
  60. - parameter initialScale: The initial scale factor used before the action button percent visible is greater than the threshold.
  61. - parameter threshold: The percent visible threshold that triggers the scaling animation.
  62. - returns: The new `ScaleTransition` instance.
  63. */
  64. public init(duration: Double = 0.15, initialScale: CGFloat = 0.8, threshold: CGFloat = 0.5) {
  65. self.duration = duration
  66. self.initialScale = initialScale
  67. self.threshold = threshold
  68. }
  69. /// :nodoc:
  70. public func didTransition(with context: SwipeActionTransitioningContext) -> Void {
  71. if context.oldPercentVisible == 0 {
  72. context.button.transform = .init(scaleX: initialScale, y: initialScale)
  73. }
  74. if context.oldPercentVisible < threshold && context.newPercentVisible >= threshold {
  75. UIView.animate(withDuration: duration) {
  76. context.button.transform = .identity
  77. }
  78. } else if context.oldPercentVisible >= threshold && context.newPercentVisible < threshold {
  79. UIView.animate(withDuration: duration) {
  80. context.button.transform = .init(scaleX: self.initialScale, y: self.initialScale)
  81. }
  82. }
  83. }
  84. }