-
-
Save MaTriXy/ebf2be6dfa0b5bbbcaa801c1d914878c 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