You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
5.1 KiB

5 years ago
  1. //
  2. // CheckMark.swift
  3. // GME Remit
  4. //
  5. // Created by InKwon James Kim on 2019/10/28.
  6. // Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10. @IBDesignable
  11. class CheckMark: UIView {
  12. enum AnimationType {
  13. case check
  14. case remove
  15. }
  16. // MARK: Public variables
  17. var animatedLayerColor: UIColor = .themeRed {
  18. didSet {
  19. animatedLayer?.strokeColor = animatedLayerColor.cgColor
  20. }
  21. }
  22. var strokeWidth: CGFloat = 4 {
  23. didSet {
  24. animatedLayer?.lineWidth = strokeWidth
  25. }
  26. }
  27. // MARK: Private variables
  28. private var animatedLayer: CAShapeLayer?
  29. // MARK: Overriding methods
  30. override init(frame: CGRect) {
  31. super.init(frame: frame)
  32. configureView()
  33. }
  34. // MARK: Public methods
  35. public required init?(coder aDecoder: NSCoder) {
  36. super.init(coder: aDecoder)
  37. configureView()
  38. }
  39. public func animate(duration: TimeInterval = 0.5, animationType: UIViewController.AlertType) {
  40. if animatedLayer == nil {
  41. animatedLayer = createCheckmarkLayer(strokeColor: animatedLayerColor, strokeEnd: 0, animationType)
  42. layer.addSublayer(animatedLayer!)
  43. }
  44. let animation = CABasicAnimation(keyPath: "strokeEnd")
  45. animation.fromValue = 0
  46. animation.toValue = 1
  47. animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
  48. animation.duration = duration
  49. animatedLayer?.strokeEnd = 1
  50. animatedLayer?.add(animation, forKey: "animateCheckmark")
  51. }
  52. public func animate(duration: TimeInterval = 0.2, animationType: AnimationType) {
  53. switch animationType {
  54. case .check:
  55. animatedLayer?.removeFromSuperlayer()
  56. animatedLayer = nil
  57. animatedLayer = createCheckmarkLayer(strokeColor: animatedLayerColor, strokeEnd: 0, .check)
  58. layer.addSublayer(animatedLayer!)
  59. case .remove:
  60. animatedLayer?.removeFromSuperlayer()
  61. animatedLayer = nil
  62. }
  63. let animation = CABasicAnimation(keyPath: "strokeEnd")
  64. animation.fromValue = 0
  65. animation.toValue = 1
  66. animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
  67. animation.duration = duration
  68. animatedLayer?.strokeEnd = 1
  69. animatedLayer?.add(animation, forKey: "animateCheckmark")
  70. }
  71. // MARK: Private methods
  72. private func configureView() {
  73. backgroundColor = UIColor.clear
  74. strokeWidth = 4
  75. }
  76. private func createCheckmarkLayer(
  77. strokeColor: UIColor,
  78. strokeEnd: CGFloat,
  79. _ type: UIViewController.AlertType
  80. ) -> CAShapeLayer {
  81. let scale = frame.width / 100
  82. let centerX = frame.size.width / 2
  83. let centerY = frame.size.height / 2
  84. let startAngle = -CGFloat(Double.pi / 2)
  85. let checkmarkPath = UIBezierPath(
  86. arcCenter: CGPoint(x: centerX, y: centerY),
  87. radius: centerX,
  88. startAngle: startAngle,
  89. endAngle: startAngle * 5,
  90. clockwise: false
  91. )
  92. switch type {
  93. case .success:
  94. checkmarkPath.move(to: CGPoint(x: centerX - 23 * scale, y: centerY - 1 * scale))
  95. checkmarkPath.addLine(to: CGPoint(x: centerX - 6 * scale, y: centerY + 15.9 * scale))
  96. checkmarkPath.addLine(to: CGPoint(x: centerX + 22.8 * scale, y: centerY - 13.4 * scale))
  97. case .error:
  98. checkmarkPath.move(to: CGPoint(x: centerX - 18 * scale, y: centerY - 18 * scale))
  99. checkmarkPath.addLine(to: CGPoint(x: centerX + 18 * scale, y: centerY + 18 * scale))
  100. checkmarkPath.move(to: CGPoint(x: centerX + 18 * scale, y: centerY - 18 * scale))
  101. checkmarkPath.addLine(to: CGPoint(x: centerX - 18 * scale, y: centerY + 18 * scale))
  102. case .normal: ()
  103. }
  104. let checkmarkLayer = CAShapeLayer()
  105. checkmarkLayer.fillColor = UIColor.clear.cgColor
  106. checkmarkLayer.lineWidth = strokeWidth
  107. checkmarkLayer.path = checkmarkPath.cgPath
  108. checkmarkLayer.strokeEnd = strokeEnd
  109. checkmarkLayer.strokeColor = strokeColor.cgColor
  110. checkmarkLayer.lineCap = CAShapeLayerLineCap.round
  111. checkmarkLayer.lineJoin = CAShapeLayerLineJoin.round
  112. return checkmarkLayer
  113. }
  114. private func createCheckmarkLayer(
  115. strokeColor: UIColor,
  116. strokeEnd: CGFloat,
  117. _ type: AnimationType
  118. ) -> CAShapeLayer {
  119. let scale = frame.width / 100
  120. let centerX = frame.size.width / 2
  121. let centerY = frame.size.height / 2
  122. let checkmarkPath = UIBezierPath()
  123. switch type {
  124. case .check:
  125. checkmarkPath.move(to: CGPoint(x: centerX - 23 * scale, y: centerY - 1 * scale))
  126. checkmarkPath.addLine(to: CGPoint(x: centerX - 6 * scale, y: centerY + 15.9 * scale))
  127. checkmarkPath.addLine(to: CGPoint(x: centerX + 22.8 * scale, y: centerY - 13.4 * scale))
  128. case .remove: ()
  129. }
  130. let checkmarkLayer = CAShapeLayer()
  131. checkmarkLayer.fillColor = UIColor.clear.cgColor
  132. checkmarkLayer.lineWidth = strokeWidth
  133. checkmarkLayer.path = checkmarkPath.cgPath
  134. checkmarkLayer.strokeEnd = strokeEnd
  135. checkmarkLayer.strokeColor = strokeColor.cgColor
  136. checkmarkLayer.lineCap = CAShapeLayerLineCap.round
  137. checkmarkLayer.lineJoin = CAShapeLayerLineJoin.round
  138. return checkmarkLayer
  139. }
  140. }