Created
July 14, 2017 11:19
-
-
Save jimmythai/540f652370629d5bc6f5f67ac33acf21 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import UIKit | |
public class Checkmark: UIView { | |
// MARK: Public variables | |
public var initialLayerColor: UIColor = UIColor.blue { | |
didSet { | |
initialLayer.strokeColor = initialLayerColor.cgColor | |
} | |
} | |
public var animatedLayerColor: UIColor = UIColor.red { | |
didSet { | |
animatedLayer?.strokeColor = animatedLayerColor.cgColor | |
} | |
} | |
public var strokeWidth: CGFloat = 4 { | |
didSet { | |
initialLayer.lineWidth = strokeWidth | |
animatedLayer?.lineWidth = strokeWidth | |
} | |
} | |
public var animated: Bool = false { | |
didSet { | |
if animated { | |
animatedLayer = createCheckmarkLayer(strokeColor: animatedLayerColor, strokeEnd: 0) | |
layer.addSublayer(animatedLayer!) | |
} | |
} | |
} | |
// MARK: Private variables | |
private lazy var initialLayer: CAShapeLayer = { | |
return self.createCheckmarkLayer(strokeColor: self.initialLayerColor, strokeEnd: 1) | |
}() | |
private var animatedLayer: CAShapeLayer? | |
// MARK: Overriding methods | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
configureView() | |
} | |
// MARK: Public methods | |
public required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
configureView() | |
} | |
public func animate(duration: TimeInterval = 0.6) { | |
guard let animatedLayer = animatedLayer else { return } | |
let animation = CABasicAnimation(keyPath: "strokeEnd") | |
animation.fromValue = 0 | |
animation.toValue = 1 | |
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) | |
animation.duration = duration | |
animatedLayer.strokeEnd = 1 | |
animatedLayer.add(animation, forKey: "animateCheckmark") | |
} | |
// MARK: Private methods | |
private func configureView() { | |
backgroundColor = UIColor.clear | |
initialLayerColor = UIColor.blue | |
animatedLayerColor = UIColor.red | |
strokeWidth = 4 | |
animated = false | |
layer.addSublayer(initialLayer) | |
} | |
private func createCheckmarkLayer(strokeColor: UIColor, strokeEnd: CGFloat) -> CAShapeLayer { | |
let scale = frame.width / 100 | |
let centerX = frame.size.width / 2 | |
let centerY = frame.size.height / 2 | |
let sixOclock = CGFloat(Double.pi / 2) | |
let checkmarkPath = UIBezierPath(arcCenter: CGPoint(x: centerX, y: centerY), radius: centerX, startAngle: sixOclock, endAngle: sixOclock * 5, clockwise: true) | |
checkmarkPath.move(to: CGPoint(x: centerX - 23 * scale, y: centerY - 1 * scale)) | |
checkmarkPath.addLine(to: CGPoint(x: centerX - 6 * scale, y: centerY + 15.9 * scale)) | |
checkmarkPath.addLine(to: CGPoint(x: centerX + 22.8 * scale, y: centerY - 13.4 * scale)) | |
let checkmarkLayer = CAShapeLayer() | |
checkmarkLayer.fillColor = UIColor.clear.cgColor | |
checkmarkLayer.lineWidth = strokeWidth | |
checkmarkLayer.path = checkmarkPath.cgPath | |
checkmarkLayer.strokeEnd = strokeEnd | |
checkmarkLayer.strokeColor = strokeColor.cgColor | |
checkmarkLayer.lineCap = kCALineCapRound | |
checkmarkLayer.lineJoin = kCALineJoinRound | |
return checkmarkLayer | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is awesome, thank you!