Skip to content

Instantly share code, notes, and snippets.

@nthState
Created July 10, 2018 14:33
Show Gist options
  • Save nthState/58cc50bf5c29d2f1765d32a915a49fc1 to your computer and use it in GitHub Desktop.
Save nthState/58cc50bf5c29d2f1765d32a915a49fc1 to your computer and use it in GitHub Desktop.
Vertical Progress Bar with stepper
import Foundation
import UIKit
@IBDesignable class VerticalProgressionBar : UIView {
@IBInspectable var sections: Int = 1 {
didSet {
build()
}
}
@IBInspectable var filled: Int = 0 {
didSet {
build()
}
}
@IBInspectable var nonFillColor: UIColor = .orange
@IBInspectable var fillColor: UIColor = .green
@IBInspectable var strokeColor: UIColor = .blue
@IBInspectable var strokeWidth: Float = 2.0
@IBInspectable var seperatorHeight: Float = 1.0
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func layoutSubviews() {
super.layoutSubviews()
build()
}
func build() {
self.backgroundColor = nonFillColor
self.layer.sublayers?.removeAll()
setupRoundedCorners()
setupBorder()
setupFillSections()
setupSectionDividers()
}
func setupRoundedCorners() {
self.layer.cornerRadius = getCornerRadius()
}
func getCornerRadius() -> CGFloat {
let width = self.frame.size.width
return width / 2
}
func setupBorder() {
self.layer.borderColor = strokeColor.cgColor
self.layer.borderWidth = CGFloat(strokeWidth)
}
func getClippingMask() -> CAShapeLayer {
let mask = UIBezierPath(roundedRect: self.bounds, cornerRadius: getCornerRadius())
let clippingMask = CAShapeLayer()
clippingMask.fillRule = kCAFillRuleEvenOdd
clippingMask.path = mask.cgPath
return clippingMask
}
func setupSectionDividers() {
if sections == 0 {
return
}
let width = self.frame.size.width
let sectionHeight = self.frame.size.height / CGFloat(sections)
for section in 1..<sections {
let y: CGFloat = CGFloat(section) * sectionHeight
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: y))
path.addLine(to: CGPoint(x: width, y: y))
let row = CAShapeLayer()
row.name = "row"
row.path = path.cgPath
row.fillColor = UIColor.clear.cgColor
row.strokeColor = strokeColor.cgColor
row.lineWidth = CGFloat(seperatorHeight)
row.lineCap = kCALineCapRound
row.mask = getClippingMask()
self.layer.addSublayer(row)
}
}
func setupFillSections() {
if filled == 0 {
return
}
let width = self.frame.size.width
let height = self.frame.size.height
let sectionHeight = height / CGFloat(sections)
for fill in 0...filled {
let y: CGFloat = height - (CGFloat(fill) * sectionHeight)
let rect = CGRect(x: 0, y: y, width: width, height: sectionHeight)
let path = UIBezierPath(rect: rect)
let row = CAShapeLayer()
row.name = "row"
row.path = path.cgPath
row.fillColor = fillColor.cgColor
row.mask = getClippingMask()
self.layer.addSublayer(row)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment