Swift - 三层环状进度条组件开发(仿Apple Watch上运动记录圆圈)
Apple Watch发布的时候,上面的有个类型仪表盘一样的圆形刻度盘让人印象深刻。它使用红绿蓝三色圆圈分别表示用户的活动,锻炼,站立情况。让人一眼就能了解自己当天的运动状况。

1,彩虹进度条开发
(1)同开发其它的自定义组件一样,我们还是通过继承 UIView 来实现。(2)整个组件由三个圆弧组成,在 drawRect() 方法中绘制添加。
(3)组件提供内、中、外三个圆圈的半径、颜色、进度属性,以及圆圈宽度属性让用户设置。
(4)组件类和属性使用IB标识,让其在StoryBoard中也能自由设置属性,并实时渲染效果。
效果图如下:


组件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import Foundation import UIKit @IBDesignable class RainbowProgressView : UIView { //进度条颜色(内圈、中间、外圈) @IBInspectable var firstColor: UIColor = UIColor ( red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0) @IBInspectable var secondColor: UIColor = UIColor ( red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0) @IBInspectable var thirdColor: UIColor = UIColor ( red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0) //进度条半径(内圈、中间、外圈) @IBInspectable var innerCircleRadius: CGFloat = 20 @IBInspectable var middleCircleRadius: CGFloat = 45 @IBInspectable var outerCircleRadius: CGFloat = 70 //进度0~1(内圈、中间、外圈) @IBInspectable var firstPercent: CGFloat = 0.75 @IBInspectable var secondPercent: CGFloat = 0.75 @IBInspectable var thirdPercent: CGFloat = 0.75 //进度条宽度 @IBInspectable var circleWeight: CGFloat = 16 required init ?(coder aDecoder: NSCoder ) { super . init (coder: aDecoder) backgroundColor = UIColor .clearColor() } override init (frame: CGRect ) { super . init (frame: frame) backgroundColor = UIColor .clearColor() } // 绘制 override func drawRect(rect: CGRect ) { // 添加三个环形进度条 self .addCirle(innerCircleRadius, color: firstColor, percent: firstPercent) self .addCirle(middleCircleRadius, color: secondColor, percent: secondPercent) self .addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent) } //添加环形进度 func addCirle(arcRadius: CGFloat , color: UIColor , percent: CGFloat ) { let X = CGRectGetMidX ( self .bounds) let Y = CGRectGetMidY ( self .bounds) // 进度条圆弧 let barPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent, strokeColor: color, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) } //添加圆弧 func addOval(lineWidth: CGFloat , path: CGPathRef , strokeStart: CGFloat , strokeEnd: CGFloat , strokeColor: UIColor , fillColor: UIColor , shadowRadius: CGFloat , shadowOpacity: Float , shadowOffsset: CGSize ) { let arc = CAShapeLayer () arc.lineWidth = lineWidth arc.path = path arc.strokeStart = strokeStart arc.strokeEnd = strokeEnd arc.strokeColor = strokeColor. CGColor arc.fillColor = fillColor. CGColor arc.shadowColor = UIColor .blackColor(). CGColor arc.shadowRadius = shadowRadius arc.shadowOpacity = shadowOpacity arc.shadowOffset = shadowOffsset layer.addSublayer(arc) } } |
测试代码:
2,组件功能改进之一:圆弧两端增加圆头
为了让圆弧没有那么生硬,我们在圆弧的两端分别添加两个圆形,这样会更圆润些。同时终点上的圆形增加了个阴影,这样效果会更好些。

改进后的组件代码(高亮处为修改的地方):
3,组件功能改进之二:添加进度条背景
看Apple Watch的运动状态圆盘可以发现,每个环形进度条后面还有一个相同色系的淡色进度槽,表示未完成的部分。
实现方式就是在各个进度条底部添加个透明圆环,颜色就是在其对应进度条颜色基础上增加透明度即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import UIKit class ViewController : UIViewController { override func viewDidLoad() { super .viewDidLoad() let rainbow1 = RainbowProgressView (frame: CGRectMake (5,20,160,160)) self .view.addSubview(rainbow1) let rainbow2 = RainbowProgressView (frame: CGRectMake (175,20,140,140)) rainbow2.circleWeight = 18 rainbow2.innerCircleRadius = 20 rainbow2.middleCircleRadius = 40 rainbow2.outerCircleRadius = 60 rainbow2.firstPercent = 0.5 rainbow2.secondPercent = 0.65 rainbow2.thirdPercent = 0.75 self .view.addSubview(rainbow2) } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |
2,组件功能改进之一:圆弧两端增加圆头
为了让圆弧没有那么生硬,我们在圆弧的两端分别添加两个圆形,这样会更圆润些。同时终点上的圆形增加了个阴影,这样效果会更好些。


改进后的组件代码(高亮处为修改的地方):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import Foundation import UIKit @IBDesignable class RainbowProgressViewEx : UIView { //进度条颜色(内圈、中间、外圈) @IBInspectable var firstColor: UIColor = UIColor ( red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0) @IBInspectable var secondColor: UIColor = UIColor ( red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0) @IBInspectable var thirdColor: UIColor = UIColor ( red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0) //进度条半径(内圈、中间、外圈) @IBInspectable var innerCircleRadius: CGFloat = 20 @IBInspectable var middleCircleRadius: CGFloat = 45 @IBInspectable var outerCircleRadius: CGFloat = 70 //进度0~1(内圈、中间、外圈) @IBInspectable var firstPercent: CGFloat = 0.75 @IBInspectable var secondPercent: CGFloat = 0.75 @IBInspectable var thirdPercent: CGFloat = 0.75 //进度条宽度 @IBInspectable var circleWeight: CGFloat = 16 required init ?(coder aDecoder: NSCoder ) { super . init (coder: aDecoder) backgroundColor = UIColor .clearColor() } override init (frame: CGRect ) { super . init (frame: frame) backgroundColor = UIColor .clearColor() } // 绘制 override func drawRect(rect: CGRect ) { // 添加三个环形进度条 self .addCirle(innerCircleRadius, color: firstColor, percent: firstPercent) self .addCirle(middleCircleRadius, color: secondColor, percent: secondPercent) self .addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent) } //添加环形进度 func addCirle(arcRadius: CGFloat , color: UIColor , percent: CGFloat ) { let X = CGRectGetMidX ( self .bounds) let Y = CGRectGetMidY ( self .bounds) // 进度条圆弧 let barPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent, strokeColor: color, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条起点圆头 let startPath = UIBezierPath (ovalInRect: CGRectMake (X-circleWeight/2, Y-arcRadius-circleWeight/2, circleWeight, circleWeight)). CGPath self .addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条终点圆头 let endDotPoint = calcCircleCoordinateWithCenter( CGPoint (x: X, y: Y), radius: arcRadius, angle: -percent*360+90) let endDotPath = UIBezierPath (ovalInRect: CGRectMake (endDotPoint.x-circleWeight/2, endDotPoint.y-circleWeight/2, circleWeight, circleWeight)). CGPath self .addOval(0.0, path: endDotPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero ) } //计算圆弧上点的坐标 func calcCircleCoordinateWithCenter(center: CGPoint , radius: CGFloat , angle: CGFloat ) -> CGPoint { let x2 = radius* CGFloat (cosf( Float (angle)* Float ( M_PI )/ Float (180))); let y2 = radius* CGFloat (sinf( Float (angle)* Float ( M_PI )/ Float (180))); return CGPointMake (center.x+x2, center.y-y2); } //添加圆弧 func addOval(lineWidth: CGFloat , path: CGPathRef , strokeStart: CGFloat , strokeEnd: CGFloat , strokeColor: UIColor , fillColor: UIColor , shadowRadius: CGFloat , shadowOpacity: Float , shadowOffsset: CGSize ) { let arc = CAShapeLayer () arc.lineWidth = lineWidth arc.path = path arc.strokeStart = strokeStart arc.strokeEnd = strokeEnd arc.strokeColor = strokeColor. CGColor arc.fillColor = fillColor. CGColor arc.shadowColor = UIColor .blackColor(). CGColor arc.shadowRadius = shadowRadius arc.shadowOpacity = shadowOpacity arc.shadowOffset = shadowOffsset layer.addSublayer(arc) } } |
看Apple Watch的运动状态圆盘可以发现,每个环形进度条后面还有一个相同色系的淡色进度槽,表示未完成的部分。
实现方式就是在各个进度条底部添加个透明圆环,颜色就是在其对应进度条颜色基础上增加透明度即可。
为了适应各种舞台背景,组件增加新属性 barBgAlpha,用于设置进度条底图的透明度。(黑色舞台背景建议0.3,白色舞台背景建议0.15)

改进后的组件代码(高亮处为修改的地方):
4,组件功能改进之三:进度条终点只有突出的部分有阴影
前面的样例中,我门是在进度条终点处添加了一个圆来实现突出的部分,所以其阴影在这个圆点周围都是存在的。
如果想要只让突出的部分周围有阴影,我门在上方覆盖一小段圆弧即可,这样就将后半部分的阴影盖住。(注意:当进度条很短的时候还需在起点处覆盖个纯色的圆点才行)


改进后的组件代码(高亮处为修改的地方):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | import Foundation import UIKit @IBDesignable class RainbowProgressViewEx2 : UIView { //进度条颜色(内圈、中间、外圈) @IBInspectable var firstColor: UIColor = UIColor ( red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0) @IBInspectable var secondColor: UIColor = UIColor ( red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0) @IBInspectable var thirdColor: UIColor = UIColor ( red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0) //进度条半径(内圈、中间、外圈) @IBInspectable var innerCircleRadius: CGFloat = 20 @IBInspectable var middleCircleRadius: CGFloat = 45 @IBInspectable var outerCircleRadius: CGFloat = 70 //进度0~1(内圈、中间、外圈) @IBInspectable var firstPercent: CGFloat = 0.75 @IBInspectable var secondPercent: CGFloat = 0.75 @IBInspectable var thirdPercent: CGFloat = 0.75 //进度条宽度 @IBInspectable var circleWeight: CGFloat = 16 //进度条背景槽透明度(黑色舞台背景建议0.3,白色舞台背景建议0.15) @IBInspectable var barBgAlpha: CGFloat = 0.3 required init ?(coder aDecoder: NSCoder ) { super . init (coder: aDecoder) backgroundColor = UIColor .clearColor() } override init (frame: CGRect ) { super . init (frame: frame) backgroundColor = UIColor .clearColor() } // 绘制 override func drawRect(rect: CGRect ) { // 添加三个环形进度条 self .addCirle(innerCircleRadius, color: firstColor, percent: firstPercent) self .addCirle(middleCircleRadius, color: secondColor, percent: secondPercent) self .addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent) } //添加环形进度 func addCirle(arcRadius: CGFloat , color: UIColor , percent: CGFloat ) { let X = CGRectGetMidX ( self .bounds) let Y = CGRectGetMidY ( self .bounds) // 进度条圆弧背景 var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 color.getRed(&r, green: &g, blue: &b, alpha: &a) let barBgColor = UIColor (red: r, green: g, blue: b, alpha: barBgAlpha); let barBgPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barBgPath, strokeStart: 0, strokeEnd: 1, strokeColor: barBgColor, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条圆弧 let barPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent, strokeColor: color, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条起点圆头 let startPath = UIBezierPath (ovalInRect: CGRectMake (X-circleWeight/2, Y-arcRadius-circleWeight/2, circleWeight, circleWeight)). CGPath self .addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条终点圆头 let endDotPoint = calcCircleCoordinateWithCenter( CGPoint (x: X, y: Y), radius: arcRadius, angle: -percent*360+90) let endDotPath = UIBezierPath (ovalInRect: CGRectMake (endDotPoint.x-circleWeight/2, endDotPoint.y-circleWeight/2, circleWeight, circleWeight)). CGPath self .addOval(0.0, path: endDotPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero ) } //计算圆弧上点的坐标 func calcCircleCoordinateWithCenter(center: CGPoint , radius: CGFloat , angle: CGFloat ) -> CGPoint { let x2 = radius* CGFloat (cosf( Float (angle)* Float ( M_PI )/ Float (180))); let y2 = radius* CGFloat (sinf( Float (angle)* Float ( M_PI )/ Float (180))); return CGPointMake (center.x+x2, center.y-y2); } //添加圆弧 func addOval(lineWidth: CGFloat , path: CGPathRef , strokeStart: CGFloat , strokeEnd: CGFloat , strokeColor: UIColor , fillColor: UIColor , shadowRadius: CGFloat , shadowOpacity: Float , shadowOffsset: CGSize ) { let arc = CAShapeLayer () arc.lineWidth = lineWidth arc.path = path arc.strokeStart = strokeStart arc.strokeEnd = strokeEnd arc.strokeColor = strokeColor. CGColor arc.fillColor = fillColor. CGColor arc.shadowColor = UIColor .blackColor(). CGColor arc.shadowRadius = shadowRadius arc.shadowOpacity = shadowOpacity arc.shadowOffset = shadowOffsset layer.addSublayer(arc) } } |
4,组件功能改进之三:进度条终点只有突出的部分有阴影
前面的样例中,我门是在进度条终点处添加了一个圆来实现突出的部分,所以其阴影在这个圆点周围都是存在的。
如果想要只让突出的部分周围有阴影,我门在上方覆盖一小段圆弧即可,这样就将后半部分的阴影盖住。(注意:当进度条很短的时候还需在起点处覆盖个纯色的圆点才行)


改进后的组件代码(高亮处为修改的地方):
源码下载:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | import Foundation import UIKit @IBDesignable class RainbowProgressViewEx3 : UIView { //进度条颜色(内圈、中间、外圈) @IBInspectable var firstColor: UIColor = UIColor ( red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0) @IBInspectable var secondColor: UIColor = UIColor ( red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0) @IBInspectable var thirdColor: UIColor = UIColor ( red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0) //进度条半径(内圈、中间、外圈) @IBInspectable var innerCircleRadius: CGFloat = 20 @IBInspectable var middleCircleRadius: CGFloat = 45 @IBInspectable var outerCircleRadius: CGFloat = 70 //进度0~1(内圈、中间、外圈) @IBInspectable var firstPercent: CGFloat = 0.75 @IBInspectable var secondPercent: CGFloat = 0.75 @IBInspectable var thirdPercent: CGFloat = 0.75 //进度条宽度 @IBInspectable var circleWeight: CGFloat = 16 //进度条背景槽透明度(黑色舞台背景建议0.3,白色舞台背景建议0.15) @IBInspectable var barBgAlpha: CGFloat = 0.3 required init ?(coder aDecoder: NSCoder ) { super . init (coder: aDecoder) backgroundColor = UIColor .clearColor() } override init (frame: CGRect ) { super . init (frame: frame) backgroundColor = UIColor .clearColor() } // 绘制 override func drawRect(rect: CGRect ) { // 添加三个环形进度条 self .addCirle(innerCircleRadius, color: firstColor, percent: firstPercent) self .addCirle(middleCircleRadius, color: secondColor, percent: secondPercent) self .addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent) } //添加环形进度 func addCirle(arcRadius: CGFloat , color: UIColor , percent: CGFloat ) { let X = CGRectGetMidX ( self .bounds) let Y = CGRectGetMidY ( self .bounds) // 进度条圆弧背景 var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 color.getRed(&r, green: &g, blue: &b, alpha: &a) let barBgColor = UIColor (red: r, green: g, blue: b, alpha: barBgAlpha); let barBgPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barBgPath, strokeStart: 0, strokeEnd: 1, strokeColor: barBgColor, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条圆弧 let barPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent, strokeColor: color, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条起点圆头 let startPath = UIBezierPath (ovalInRect: CGRectMake (X-circleWeight/2, Y-arcRadius-circleWeight/2, circleWeight, circleWeight)). CGPath self .addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条终点圆头 let endDotPoint = calcCircleCoordinateWithCenter( CGPoint (x: X, y: Y), radius: arcRadius, angle: -percent*360+90) let endDotPath = UIBezierPath (ovalInRect: CGRectMake (endDotPoint.x-circleWeight/2, endDotPoint.y-circleWeight/2, circleWeight, circleWeight)). CGPath self .addOval(0.0, path: endDotPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero ) // 进度条遮罩1(圆弧) let barMaskPath = UIBezierPath (arcCenter: CGPoint (x: X, y: Y), radius: arcRadius, startAngle: CGFloat (- M_PI_2 ), endAngle: CGFloat ( M_PI *1.5), clockwise: true ). CGPath self .addOval(circleWeight, path: barMaskPath, strokeStart: percent/6, strokeEnd: percent, strokeColor: color, fillColor: UIColor .clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) // 进度条遮罩2(圆) if percent < 0.5{ self .addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero ) } } //计算圆弧上点的坐标 func calcCircleCoordinateWithCenter(center: CGPoint , radius: CGFloat , angle: CGFloat ) -> CGPoint { let x2 = radius* CGFloat (cosf( Float (angle)* Float ( M_PI )/ Float (180))); let y2 = radius* CGFloat (sinf( Float (angle)* Float ( M_PI )/ Float (180))); return CGPointMake (center.x+x2, center.y-y2); } //添加圆弧 func addOval(lineWidth: CGFloat , path: CGPathRef , strokeStart: CGFloat , strokeEnd: CGFloat , strokeColor: UIColor , fillColor: UIColor , shadowRadius: CGFloat , shadowOpacity: Float , shadowOffsset: CGSize ) { let arc = CAShapeLayer () arc.lineWidth = lineWidth arc.path = path arc.strokeStart = strokeStart arc.strokeEnd = strokeEnd arc.strokeColor = strokeColor. CGColor arc.fillColor = fillColor. CGColor arc.shadowColor = UIColor .blackColor(). CGColor arc.shadowRadius = shadowRadius arc.shadowOpacity = shadowOpacity arc.shadowOffset = shadowOffsset layer.addSublayer(arc) } } |

不需要旋转,谢谢了。
航哥,你好,请问下如果想做示例中的一个圆环,只是圆环从0到persent为0.5(或者其它值)的时候加动画,并且加一张图片跟着这个动画的路径从0走,该怎么做呢?我现在用UIView的animation动画改变arc.strokeEnd可以实现圆环的行走动画,但是UIImageView的动画加上去很麻烦也无法跟圆环的头同步走。