Created
December 24, 2015 15:52
-
-
Save syshen/6f9ed9bf9e59c27a3feb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wrong animation example