Skip to content

Instantly share code, notes, and snippets.

@syshen
Created December 24, 2015 15:52
Show Gist options
  • Save syshen/6f9ed9bf9e59c27a3feb to your computer and use it in GitHub Desktop.
Save syshen/6f9ed9bf9e59c27a3feb to your computer and use it in GitHub Desktop.
public class PieProgressView: UIView {
public var progress:Float {
get {
return _progress
}
set {
_progress = newValue
self.updatePath()
}
}
var borderWidth:Float = 2.0 {
didSet {
self.updatePath()
}
}
override public var frame:CGRect {
didSet {
self.updatePath()
}
}
static private let animationDuration = 0.6
public func setProgress(progress:Float, animated:Bool) {
_progress = progress
self.updatePath(animated)
}
private var _progress:Float = 0.0
init() {
super.init(frame: CGRectZero)
self.initialize()
}
override public init(frame: CGRect) {
super.init(frame:frame)
self.initialize()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}
public var fillColor:UIColor = UIColor.lightGrayColor() {
didSet {
self.shapeLayer.fillColor = self.fillColor.CGColor
}
}
public var backgroundFillColor:UIColor = UIColor(red: 250.0/255.0, green: 250.0/255.0, blue: 250.0/255.0, alpha: 0.6) {
didSet {
self.backgroundShapeLayer.fillColor = self.backgroundFillColor.CGColor
}
}
private let shapeLayer = CAShapeLayer()
private let backgroundShapeLayer = CAShapeLayer()
private func initialize() {
self.backgroundColor = UIColor.clearColor()
self.backgroundShapeLayer.fillColor = self.backgroundFillColor.CGColor
self.layer.addSublayer(self.backgroundShapeLayer)
self.shapeLayer.fillColor = self.fillColor.CGColor
// self.shapeLayer.strokeColor = UIColor.redColor().CGColor
self.layer.addSublayer(self.shapeLayer)
self.updatePath()
}
private func updatePath(animated:Bool = false) {
self.backgroundShapeLayer.path = UIBezierPath(ovalInRect: self.bounds).CGPath
let center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds))
let radius = center.y - CGFloat(2 * self.borderWidth)
let angle = DegreesToRadians(Double((360.0 * _progress) + -90.0))
let points = [CGPointMake(center.x, CGFloat(self.borderWidth)),
center,
CGPointMake(center.x + radius * CGFloat(cosf(Float(angle))), center.y + radius * CGFloat(sinf(Float(angle))))]
let path = UIBezierPath()
path.moveToPoint(points[2])
path.addLineToPoint(points[1])
path.addLineToPoint(points[0])
path.addArcWithCenter(center, radius: radius, startAngle: CGFloat(DegreesToRadians(-90)), endAngle: CGFloat(angle), clockwise: true)
if animated {
let animation = CABasicAnimation(keyPath: "path")
animation.duration = PieProgressView.animationDuration
animation.fillMode = kCAFillModeForwards
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.removedOnCompletion = true
animation.fromValue = self.shapeLayer.path
animation.toValue = path.CGPath
self.shapeLayer.path = path.CGPath
self.shapeLayer.addAnimation(animation, forKey: "path")
} else {
self.shapeLayer.path = path.CGPath
}
}
}
@syshen
Copy link
Author

syshen commented Dec 24, 2015

Wrong animation example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment