AnimatableCheckBox.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. //
  2. // Created by Jake Lin on 12/20/15.
  3. // Copyright © 2015 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. @IBDesignable
  7. open class AnimatableCheckBox: UIButton, CheckBoxDesignable, CornerDesignable, FillDesignable,
  8. BorderDesignable, ShadowDesignable, MaskDesignable,
  9. Animatable {
  10. // MARK: - CheckBoxDesignable
  11. @IBInspectable open var checked: Bool = false {
  12. didSet {
  13. configureCheckBoxChecked()
  14. }
  15. }
  16. @IBInspectable open var checkedImage: UIImage? {
  17. didSet {
  18. configureCheckBoxCheckedImage()
  19. }
  20. }
  21. @IBInspectable open var uncheckedImage: UIImage? {
  22. didSet {
  23. configureCheckBoxUncheckedImage()
  24. }
  25. }
  26. // MARK: - CornerDesignable
  27. @IBInspectable open var cornerRadius: CGFloat = CGFloat.nan {
  28. didSet {
  29. configureCornerRadius()
  30. }
  31. }
  32. open var cornerSides: CornerSides = .allSides {
  33. didSet {
  34. configureCornerRadius()
  35. }
  36. }
  37. @IBInspectable var _cornerSides: String? {
  38. didSet {
  39. cornerSides = CornerSides(rawValue: _cornerSides)
  40. }
  41. }
  42. // MARK: - FillDesignable
  43. @IBInspectable open var fillColor: UIColor? {
  44. didSet {
  45. configureFillColor()
  46. }
  47. }
  48. open var predefinedColor: ColorType? {
  49. didSet {
  50. configureFillColor()
  51. }
  52. }
  53. @IBInspectable var _predefinedColor: String? {
  54. didSet {
  55. predefinedColor = ColorType(string: _predefinedColor)
  56. }
  57. }
  58. @IBInspectable open var opacity: CGFloat = CGFloat.nan {
  59. didSet {
  60. configureOpacity()
  61. }
  62. }
  63. // MARK: - BorderDesignable
  64. open var borderType: BorderType = .solid {
  65. didSet {
  66. configureBorder()
  67. }
  68. }
  69. @IBInspectable var _borderType: String? {
  70. didSet {
  71. borderType = BorderType(string: _borderType)
  72. }
  73. }
  74. @IBInspectable open var borderColor: UIColor? {
  75. didSet {
  76. configureBorder()
  77. }
  78. }
  79. @IBInspectable open var borderWidth: CGFloat = CGFloat.nan {
  80. didSet {
  81. configureBorder()
  82. }
  83. }
  84. open var borderSides: BorderSides = .AllSides {
  85. didSet {
  86. configureBorder()
  87. }
  88. }
  89. @IBInspectable var _borderSides: String? {
  90. didSet {
  91. borderSides = BorderSides(rawValue: _borderSides)
  92. }
  93. }
  94. // MARK: - ShadowDesignable
  95. @IBInspectable open var shadowColor: UIColor? {
  96. didSet {
  97. configureShadowColor()
  98. }
  99. }
  100. @IBInspectable open var shadowRadius: CGFloat = CGFloat.nan {
  101. didSet {
  102. configureShadowRadius()
  103. }
  104. }
  105. @IBInspectable open var shadowOpacity: CGFloat = CGFloat.nan {
  106. didSet {
  107. configureShadowOpacity()
  108. }
  109. }
  110. @IBInspectable open var shadowOffset: CGPoint = CGPoint(x: CGFloat.nan, y: CGFloat.nan) {
  111. didSet {
  112. configureShadowOffset()
  113. }
  114. }
  115. // MARK: - MaskDesignable
  116. open var maskType: MaskType = .none {
  117. didSet {
  118. configureMask(previousMaskType: oldValue)
  119. configureBorder()
  120. }
  121. }
  122. /// The mask type used in Interface Builder. **Should not** use this property in code.
  123. @IBInspectable var _maskType: String? {
  124. didSet {
  125. maskType = MaskType(string: _maskType)
  126. }
  127. }
  128. // MARK: - Animatable
  129. open var animationType: AnimationType = .none
  130. @IBInspectable var _animationType: String? {
  131. didSet {
  132. animationType = AnimationType(string: _animationType)
  133. }
  134. }
  135. @IBInspectable open var autoRun: Bool = true
  136. @IBInspectable open var duration: Double = Double.nan
  137. @IBInspectable open var delay: Double = Double.nan
  138. @IBInspectable open var damping: CGFloat = CGFloat.nan
  139. @IBInspectable open var velocity: CGFloat = CGFloat.nan
  140. @IBInspectable open var force: CGFloat = CGFloat.nan
  141. @IBInspectable var _timingFunction: String = "" {
  142. didSet {
  143. timingFunction = TimingFunctionType(string: _timingFunction)
  144. }
  145. }
  146. open var timingFunction: TimingFunctionType = .none
  147. // MARK: - Lifecycle
  148. open override func prepareForInterfaceBuilder() {
  149. super.prepareForInterfaceBuilder()
  150. setup()
  151. configureInspectableProperties()
  152. }
  153. open override func awakeFromNib() {
  154. super.awakeFromNib()
  155. setup()
  156. configureInspectableProperties()
  157. }
  158. open override func layoutSubviews() {
  159. super.layoutSubviews()
  160. configureAfterLayoutSubviews()
  161. autoRunAnimation()
  162. }
  163. open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
  164. if isTouchInside {
  165. checked = !checked
  166. sendActions(for: .valueChanged)
  167. }
  168. super.touchesEnded(touches, with: event)
  169. }
  170. // MARK: - Private
  171. fileprivate func setup() {
  172. // No title for CheckBox
  173. setTitle("", for: UIControl.State())
  174. tintColor = .clear
  175. }
  176. fileprivate func configureInspectableProperties() {
  177. configureAnimatableProperties()
  178. }
  179. fileprivate func configureAfterLayoutSubviews() {
  180. configureMask(previousMaskType: maskType)
  181. configureCornerRadius()
  182. configureBorder()
  183. }
  184. }