Skip to content

Instantly share code, notes, and snippets.

@zigdanis
Created June 14, 2017 08:54
Show Gist options
  • Save zigdanis/6fb72728b13fd8825cabc86c0d61e489 to your computer and use it in GitHub Desktop.
Save zigdanis/6fb72728b13fd8825cabc86c0d61e489 to your computer and use it in GitHub Desktop.
//
// ProgressCircle.swift
// Quicker
//
// Created by Danis Ziganshin on 13/06/2017.
// Copyright © 2017 ZedPlus. All rights reserved.
//
import Foundation
import UIKit
class ProgressCircle: UIView {
private let lineWidth: CGFloat = 4
private var segments = [Int: UIColor]()
private let total: Int
init(frame: CGRect, total: Int) {
self.total = total
for i in 0..<total {
segments[i] = UIColor.appGrey
}
super.init(frame: frame)
backgroundColor = UIColor.clear
}
@available(*, unavailable)
override init(frame: CGRect) {
fatalError("init(frame:) has not been implemented")
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let center = CGPoint(x: rect.midX, y: rect.midY)
let radius = rect.width / 2 - lineWidth / 2
let sorted = segments.sorted(by: { $0.key < $1.key })
assert(sorted.count == total)
for (index, color) in sorted {
let (start, end) = startAndEndRadiansFor(index: index)
color.setStroke()
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: start, endAngle: end, clockwise: true)
path.lineWidth = lineWidth
path.stroke()
}
}
public func updateSegments(with dict: [Int: UIColor]) {
segments = dict
setNeedsDisplay()
}
// MARK: - Private
private func startAndEndRadiansFor(index: Int) -> (CGFloat, CGFloat) {
assert(index < total)
let step = CGFloat(360 / total)
let start = CGFloat(index) * step
let end = start + step
let startRadian = CGFloat(start - 90) * CGFloat.pi / 180.0
let endRadian = CGFloat(end - 90) * CGFloat.pi / 180.0
return (startRadian, endRadian)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment