Skip to content

Instantly share code, notes, and snippets.

@victorBaro victorBaro/CheckMarkView.playground Secret
Last active May 5, 2018

Embed
What would you like to do?
Example Playground for a custom checkmark control
import UIKit
import PlaygroundSupport
let viewportSize = CGRect(x: 0, y: 0, width: 300, height: 300)
struct CheckMarkViewStyle {
let checkMarkColor: UIColor
let lineWidth: CGFloat
let backgroundColor: UIColor
static var blackStyle: CheckMarkViewStyle {
return CheckMarkViewStyle(checkMarkColor: UIColor.black,
lineWidth: 15,
backgroundColor: UIColor.black.withAlphaComponent(0.4))
}
static var thinBlueStyle: CheckMarkViewStyle {
return CheckMarkViewStyle(checkMarkColor: UIColor.white,
lineWidth: 8,
backgroundColor: UIColor.blue.withAlphaComponent(0.4))
}
}
class CheckMarkView: UIControl {
var style: CheckMarkViewStyle = CheckMarkViewStyle.blackStyle {
didSet {
updateStyle()
}
}
override var isSelected: Bool {
didSet {
updateLayerProgress()
}
}
private var checkMarkLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func layoutSubviews() {
super.layoutSubviews()
updateCheckmarkLayerForViewBounds()
layer.cornerRadius = bounds.width / 2
}
private func setup() {
addCheckmarkLayer()
updateStyle()
updateLayerProgress()
}
private func addCheckmarkLayer() {
checkMarkLayer.fillColor = UIColor.clear.cgColor
updateCheckmarkLayerForViewBounds()
layer.addSublayer(checkMarkLayer)
}
private func updateCheckmarkLayerForViewBounds() {
checkMarkLayer.frame = bounds
checkMarkLayer.path = checkmarkPathInRect(rect: bounds)
}
private func updateStyle() {
checkMarkLayer.lineWidth = style.lineWidth
checkMarkLayer.strokeColor = style.checkMarkColor.cgColor
backgroundColor = style.backgroundColor
}
private func updateLayerProgress() {
checkMarkLayer.strokeEnd = isSelected ? 1 : 0
}
fileprivate func checkmarkPathInRect(rect: CGRect) -> CGPath {
//This points are extracted from PaintCode
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 0.34659 * rect.width, y: 0.50568 * rect.height))
bezierPath.addLine(to: CGPoint(x: 0.43750 * rect.width, y: 0.59659 * rect.height))
bezierPath.addLine(to: CGPoint(x: 0.65341 * rect.width, y: 0.38068 * rect.height))
return bezierPath.cgPath
}
}
class PlaygroundController: UIViewController {
private var checkMarkView: CheckMarkView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let checkFrame = CGRect(origin: .zero, size: CGSize(width: 200, height: 200))
checkMarkView = CheckMarkView(frame: checkFrame)
// checkMarkView.style = CheckMarkViewStyle.thinBlueStyle
view.addSubview(checkMarkView)
let tap = UITapGestureRecognizer(target: self, action: #selector(checkMarkTapped))
checkMarkView.addGestureRecognizer(tap)
}
private dynamic func checkMarkTapped() {
checkMarkView.isSelected = !checkMarkView.isSelected
}
}
let controller = PlaygroundController()
controller.view.frame = viewportSize
PlaygroundPage.current.liveView = controller.view
PlaygroundPage.current.needsIndefiniteExecution = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.