swift 2.2
import UIKit
class ProgressView: UIView {
/// 灰色线条的颜色
var strokelineWidth:CGFloat = 10.0
/// 中间字的大小
var numbelFont = UIFont.systemFontOfSize(18)
/// 中间字的颜色
var numbelTextColor = UIColor.blackColor()
/// 内部轨道颜色
var interiorRailwayColor = UIColor.lightGrayColor()
/// 外部轨道颜色
var exteriorRailwayColor = UIColor.redColor()
private var progressValue : CGFloat!
private var progressFlag : CGFloat!
var labelTimer : NSTimer?
lazy var outLayer : CAShapeLayer! = {
let Layer = CAShapeLayer()
Layer.strokeColor = UIColor.lightGrayColor().CGColor
Layer.fillColor = UIColor.clearColor().CGColor
Layer.lineCap = kCALineCapRound
self.layer.addSublayer(Layer)
return Layer
}()
lazy var progressLayer : CAShapeLayer! = {
let layerNew = CAShapeLayer()
layerNew.fillColor = UIColor.clearColor().CGColor
layerNew.strokeColor = UIColor.redColor().CGColor
//progressLayer.lineCap = kCALineCapRound
self.layer.addSublayer(layerNew)
return layerNew
}()
lazy var numberLabel : UILabel! = {
let numLabelNew = UILabel(frame: CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height))
numLabelNew.center = CGPointMake(self.bounds.size.width / 2,self.bounds.size.height/2)
numLabelNew.backgroundColor = UIColor.clearColor()
numLabelNew.textAlignment = .Center
self.addSubview(numLabelNew)
return numLabelNew
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.whiteColor()
}
/**
调整绘制图像
- parameter progress: 90
- parameter animate: true or false
*/
func circleWithProgress(progress: CGFloat,andIsAnimate animate : Bool){
if(animate){
progressFlag = 0
progressValue = progress
// 灰色轨道
let path = UIBezierPath(arcCenter: CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2), radius: self.bounds.size.width / 2 - strokelineWidth / 2 - 5, startAngle: CGFloat(0) , endAngle: CGFloat( M_PI * 2) , clockwise: true)
self.outLayer.path = path.CGPath
self.outLayer.lineWidth = strokelineWidth
self.outLayer.strokeColor = interiorRailwayColor.CGColor
// run轨道
let path1 = UIBezierPath(arcCenter: CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2), radius: self.bounds.size.width/2 - strokelineWidth / 2 - 2.5 , startAngle: -CGFloat(M_PI * 0.5) , endAngle: CGFloat(M_PI * 1.5) , clockwise: true)
self.progressLayer.path = path1.CGPath
self.progressLayer.lineWidth = strokelineWidth + 5
self.progressLayer.strokeColor = exteriorRailwayColor.CGColor
let pathAnima = CABasicAnimation(keyPath: "strokeEnd")
pathAnima.duration = Double(progress / 100.0)
pathAnima.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
pathAnima.fromValue = NSNumber(float: 0)
pathAnima.toValue = NSNumber(float: Float(progress / 100.0))
pathAnima.fillMode = kCAFillModeForwards
pathAnima.removedOnCompletion = false
self.progressLayer.addAnimation(pathAnima, forKey: "strokeEndAnimation")
self.numberLabel.font = numbelFont
self.numberLabel.textColor = numbelTextColor
if(progress > 0){
labelTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "nameLbChange", userInfo: nil, repeats: true)
}
}else{
self.numberLabel.text = "\(Int(progress))%"
self.numberLabel.font = numbelFont
self.numberLabel.textColor = numbelTextColor
let path = UIBezierPath(arcCenter: CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2), radius: self.bounds.size.width / 2 - strokelineWidth / 2 - 5, startAngle: CGFloat(0) , endAngle: CGFloat( M_PI * 2) , clockwise: true)
self.outLayer.path = path.CGPath
self.outLayer.lineWidth = strokelineWidth
self.outLayer.strokeColor = interiorRailwayColor.CGColor
let path1 = UIBezierPath(arcCenter: CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2), radius: self.bounds.size.width/2 - strokelineWidth / 2 - 2.5 , startAngle: -CGFloat(M_PI * 0.5) , endAngle: CGFloat(M_PI * 1.5) , clockwise: true)
self.progressLayer.path = path1.CGPath
self.progressLayer.lineWidth = strokelineWidth + 5
self.progressLayer.strokeEnd = progress / 100.0
self.progressLayer.strokeColor = exteriorRailwayColor.CGColor
}
}
/**
定时器走的方法
*/
func nameLbChange(){
if(progressFlag >= progressValue - 1){
labelTimer!.invalidate()
labelTimer = nil
}
progressFlag! += CGFloat(1.0)
numberLabel.text = "\(Int(progressFlag))%"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
swift 3++
import UIKit
class CNCircleProgressView: UIView {
/// 灰色线条的颜色
var strokelineWidth:CGFloat = 10.0
/// 中间字的大小
var numbelFont = UIFont.systemFont(ofSize: 18)
/// 中间字的颜色
var numbelTextColor = UIColor.black
/// 内部轨道颜色
var interiorRailwayColor = UIColor.lightGray
/// 外部轨道颜色
var exteriorRailwayColor = UIColor.red
/// label定时器
var labelTimer : Timer?
/// 总的进度
private var progressValue : CGFloat!
/// 累加的进度
private var progressFlag : CGFloat!
/// 轨道layer
private lazy var interiorRailwayLayer : CAShapeLayer! = {
let Layer = CAShapeLayer()
Layer.strokeColor = UIColor.lightGray.cgColor
Layer.fillColor = UIColor.clear.cgColor
Layer.lineCap = kCALineCapRound
self.layer.addSublayer(Layer)
return Layer
}()
/// 加载轨道layer
private lazy var exteriorRailwayLayer : CAShapeLayer! = {
let layerNew = CAShapeLayer()
layerNew.fillColor = UIColor.clear.cgColor
layerNew.strokeColor = UIColor.red.cgColor
//progressLayer.lineCap = kCALineCapRound
self.layer.addSublayer(layerNew)
return layerNew
}()
/// 中间显示数字
private lazy var numberLabel : UILabel! = {
let numLabelNew = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
numLabelNew.center = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height/2)
numLabelNew.backgroundColor = UIColor.clear
numLabelNew.textAlignment = .center
self.addSubview(numLabelNew)
return numLabelNew
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
}
/**
调整绘制图像
- parameter progress: 90
- parameter animate: true or false
*/
func circleWithProgress(progress: CGFloat,andIsAnimate animate : Bool){
if animate {
progressFlag = 0
progressValue = progress
let path = UIBezierPath(arcCenter: CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height/2), radius: self.bounds.size.width / 2 - strokelineWidth / 2 - 5, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true)
self.interiorRailwayLayer.path = path.cgPath
self.interiorRailwayLayer.lineWidth = strokelineWidth
self.interiorRailwayLayer.strokeColor = interiorRailwayColor.cgColor
let pathE = UIBezierPath(arcCenter: CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height/2), radius: self.bounds.size.width / 2 - strokelineWidth / 2 - 2.5, startAngle: -CGFloat(M_PI * 0.5), endAngle: CGFloat(M_PI * 1.5), clockwise: true)
self.exteriorRailwayLayer.path = pathE.cgPath
self.exteriorRailwayLayer.lineWidth = strokelineWidth + 5
self.exteriorRailwayLayer.strokeColor = exteriorRailwayColor.cgColor
let pathAnima = CABasicAnimation(keyPath: "strokeEnd")
pathAnima.duration = Double(progress / 100.0)
pathAnima.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
pathAnima.fromValue = NSNumber(value: 0)
pathAnima.toValue = NSNumber(value: Float(progress / 100.0))
pathAnima.fillMode = kCAFillModeForwards
pathAnima.isRemovedOnCompletion = false
self.exteriorRailwayLayer.add(pathAnima, forKey: "strokeEndAnimation")
self.numberLabel.font = numbelFont
self.numberLabel.textColor = numbelTextColor
if progress > 0 {
labelTimer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(CNCircleProgressView.nameLbChange), userInfo: nil, repeats: true)
}
}else{
self.numberLabel.text = "\(Int(progress))%"
self.numberLabel.font = numbelFont
self.numberLabel.textColor = numbelTextColor
let path = UIBezierPath(arcCenter: CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height/2), radius: self.bounds.size.width / 2 - strokelineWidth / 2 - 5, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true)
self.interiorRailwayLayer.path = path.cgPath
self.interiorRailwayLayer.lineWidth = strokelineWidth
self.interiorRailwayLayer.strokeColor = interiorRailwayColor.cgColor
let pathE = UIBezierPath(arcCenter: CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height/2), radius: self.bounds.size.width / 2 - strokelineWidth / 2 - 2.5, startAngle: -CGFloat(M_PI * 0.5), endAngle: CGFloat(M_PI * 1.5), clockwise: true)
self.exteriorRailwayLayer.path = pathE.cgPath
self.exteriorRailwayLayer.lineWidth = strokelineWidth + 5
self.exteriorRailwayLayer.strokeColor = exteriorRailwayColor.cgColor
self.exteriorRailwayLayer.strokeEnd = progress / 100.0
}
}
/**
定时器走的方法
*/
func nameLbChange(){
if(progressFlag >= progressValue - 1){
labelTimer!.invalidate()
labelTimer = nil
}
progressFlag! += CGFloat(1.0)
numberLabel.text = "\(Int(progressFlag))%"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}