Skip to content

Instantly share code, notes, and snippets.

@victorBaro
Last active May 5, 2018 21:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorBaro/067f81d5a1b0b1f239833dfd17ba4bd8 to your computer and use it in GitHub Desktop.
Save victorBaro/067f81d5a1b0b1f239833dfd17ba4bd8 to your computer and use it in GitHub Desktop.
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