AnimatableStackView.swift 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //
  2. // Created by Jake Lin on 12/11/15.
  3. // Copyright © 2015 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. // FIXME: almost same as `AnimatableView`, Need to refactor to encasuplate.
  7. @IBDesignable
  8. open class AnimatableStackView: UIStackView, CornerDesignable, FillDesignable, BorderDesignable,
  9. RotationDesignable, ShadowDesignable, TintDesignable, GradientDesignable,
  10. MaskDesignable, Animatable {
  11. // MARK: - CornerDesignable
  12. @IBInspectable open var cornerRadius: CGFloat = CGFloat.nan {
  13. didSet {
  14. configureCornerRadius()
  15. }
  16. }
  17. open var cornerSides: CornerSides = .allSides {
  18. didSet {
  19. configureCornerRadius()
  20. }
  21. }
  22. @IBInspectable var _cornerSides: String? {
  23. didSet {
  24. cornerSides = CornerSides(rawValue: _cornerSides)
  25. }
  26. }
  27. // MARK: - FillDesignable
  28. @IBInspectable open var fillColor: UIColor? {
  29. didSet {
  30. configureFillColor()
  31. }
  32. }
  33. open var predefinedColor: ColorType? {
  34. didSet {
  35. configureFillColor()
  36. }
  37. }
  38. @IBInspectable var _predefinedColor: String? {
  39. didSet {
  40. predefinedColor = ColorType(string: _predefinedColor)
  41. }
  42. }
  43. @IBInspectable open var opacity: CGFloat = CGFloat.nan {
  44. didSet {
  45. configureOpacity()
  46. }
  47. }
  48. // MARK: - BorderDesignable
  49. open var borderType: BorderType = .solid {
  50. didSet {
  51. configureBorder()
  52. }
  53. }
  54. @IBInspectable var _borderType: String? {
  55. didSet {
  56. borderType = BorderType(string: _borderType)
  57. }
  58. }
  59. @IBInspectable open var borderColor: UIColor? {
  60. didSet {
  61. configureBorder()
  62. }
  63. }
  64. @IBInspectable open var borderWidth: CGFloat = CGFloat.nan {
  65. didSet {
  66. configureBorder()
  67. }
  68. }
  69. open var borderSides: BorderSides = .AllSides {
  70. didSet {
  71. configureBorder()
  72. }
  73. }
  74. @IBInspectable var _borderSides: String? {
  75. didSet {
  76. borderSides = BorderSides(rawValue: _borderSides)
  77. }
  78. }
  79. // MARK: - RotationDesignable
  80. @IBInspectable open var rotate: CGFloat = CGFloat.nan {
  81. didSet {
  82. configureRotate()
  83. }
  84. }
  85. // MARK: - ShadowDesignable
  86. @IBInspectable open var shadowColor: UIColor? {
  87. didSet {
  88. configureShadowColor()
  89. }
  90. }
  91. @IBInspectable open var shadowRadius: CGFloat = CGFloat.nan {
  92. didSet {
  93. configureShadowRadius()
  94. }
  95. }
  96. @IBInspectable open var shadowOpacity: CGFloat = CGFloat.nan {
  97. didSet {
  98. configureShadowOpacity()
  99. }
  100. }
  101. @IBInspectable open var shadowOffset: CGPoint = CGPoint(x: CGFloat.nan, y: CGFloat.nan) {
  102. didSet {
  103. configureShadowOffset()
  104. }
  105. }
  106. // MARK: - TintDesignable
  107. @IBInspectable open var tintOpacity: CGFloat = CGFloat.nan
  108. @IBInspectable open var shadeOpacity: CGFloat = CGFloat.nan
  109. @IBInspectable open var toneColor: UIColor?
  110. @IBInspectable open var toneOpacity: CGFloat = CGFloat.nan
  111. // MARK: - GradientDesignable
  112. open var gradientMode: GradientMode = .linear
  113. @IBInspectable var _gradientMode: String? {
  114. didSet {
  115. gradientMode = GradientMode(string: _gradientMode) ?? .linear
  116. }
  117. }
  118. @IBInspectable open var startColor: UIColor?
  119. @IBInspectable open var endColor: UIColor?
  120. open var predefinedGradient: GradientType?
  121. @IBInspectable var _predefinedGradient: String? {
  122. didSet {
  123. predefinedGradient = GradientType(string: _predefinedGradient)
  124. }
  125. }
  126. open var startPoint: GradientStartPoint = .top
  127. @IBInspectable var _startPoint: String? {
  128. didSet {
  129. startPoint = GradientStartPoint(string: _startPoint, default: .top)
  130. }
  131. }
  132. // MARK: - MaskDesignable
  133. open var maskType: MaskType = .none {
  134. didSet {
  135. configureMask(previousMaskType: oldValue)
  136. configureBorder()
  137. }
  138. }
  139. /// The mask type used in Interface Builder. **Should not** use this property in code.
  140. @IBInspectable var _maskType: String? {
  141. didSet {
  142. maskType = MaskType(string: _maskType)
  143. }
  144. }
  145. // MARK: - Animatable
  146. open var animationType: AnimationType = .none
  147. @IBInspectable var _animationType: String? {
  148. didSet {
  149. animationType = AnimationType(string: _animationType)
  150. }
  151. }
  152. @IBInspectable open var autoRun: Bool = true
  153. @IBInspectable open var duration: Double = Double.nan
  154. @IBInspectable open var delay: Double = Double.nan
  155. @IBInspectable open var damping: CGFloat = CGFloat.nan
  156. @IBInspectable open var velocity: CGFloat = CGFloat.nan
  157. @IBInspectable open var force: CGFloat = CGFloat.nan
  158. @IBInspectable var _timingFunction: String = "" {
  159. didSet {
  160. timingFunction = TimingFunctionType(string: _timingFunction)
  161. }
  162. }
  163. open var timingFunction: TimingFunctionType = .none
  164. // MARK: - Lifecycle
  165. open override func prepareForInterfaceBuilder() {
  166. super.prepareForInterfaceBuilder()
  167. configureInspectableProperties()
  168. }
  169. open override func awakeFromNib() {
  170. super.awakeFromNib()
  171. configureInspectableProperties()
  172. }
  173. open override func layoutSubviews() {
  174. super.layoutSubviews()
  175. configureAfterLayoutSubviews()
  176. autoRunAnimation()
  177. }
  178. // MARK: - Private
  179. fileprivate func configureInspectableProperties() {
  180. configureAnimatableProperties()
  181. configureTintedColor()
  182. }
  183. fileprivate func configureAfterLayoutSubviews() {
  184. configureMask(previousMaskType: maskType)
  185. configureCornerRadius()
  186. configureBorder()
  187. configureGradient()
  188. }
  189. }