封装一个UILabel圆形边框显示进度

时间:2023-03-08 22:14:55

封装了一个UILabel并让它显示圆形的边框,UILabel上面显示百份比,而边框则用Animation绘制到整个圆占指定百分比的点。

封装一个UILabel圆形边框显示进度

这只是我个人想的继承一个UILabel实现的,用到两个CAShapeLayer,第一个Layer的作用是画出灰色的背影圆圈,第二个Layer位置放置在第一个Layer的上面,并设置为红色描绘颜色并描绘到插定的位置,之后实现相应的动画效果即可。

import UIKit

class kCircleLabel: UILabel {

    var percent:Double!

    convenience init(percent per:Double,frame:CGRect) {
self.init(frame: frame)
self.percent = per
createCircle()
} override init(frame: CGRect) {
super.init(frame: frame)
} required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
} func createCircle() {
self.textAlignment = NSTextAlignment.Center
self.text = "\(percent * 100 )%" //第一个圆形Layer,边框为灰色的
let circleLayer:CAShapeLayer = CAShapeLayer()
circleLayer.lineWidth = 8
//清除填充的颜色
circleLayer.fillColor = UIColor.clearColor().CGColor
//边框的颜色
circleLayer.strokeColor = UIColor.init(red: CGFloat(220.0 / 255.0 ), green: CGFloat(220.0 / 255.0), blue: CGFloat(220.0 / 255.0), alpha: 1.0).CGColor //用贝塞尔曲线画出一个圆
let circlePath:UIBezierPath = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)) circleLayer.path = circlePath.CGPath
self.layer.addSublayer(circleLayer) //第二个只描绘到特定位置的弧Layer
let arcLayer:CAShapeLayer = CAShapeLayer() //画出特定的弧
let arcPath:UIBezierPath = UIBezierPath(arcCenter: CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2), radius: self.frame.size.width / 2, startAngle: 0.0, endAngle: CGFloat(360 * percent / 180 * M_PI), clockwise: true) arcLayer.path = arcPath.CGPath
arcLayer.lineWidth = 8
//清除填充的颜色
arcLayer.fillColor = UIColor.clearColor().CGColor
arcLayer.strokeColor = UIColor.redColor().CGColor //弧Layer的动画
let arcAnimation:CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd")
arcAnimation.fromValue = 0.0
arcAnimation.toValue = 1.0
arcAnimation.duration = 1.5
arcAnimation.removedOnCompletion = false
arcAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) //这是从大到小的动画,适用于整个Layer
let scaleAnimation:CABasicAnimation = CABasicAnimation(keyPath: "transform.scale")
scaleAnimation.fromValue = 5.0
scaleAnimation.toValue = 1.0
scaleAnimation.duration = 0.5 arcLayer.addAnimation(arcAnimation, forKey: nil) /*let animationGroup:CAAnimationGroup = CAAnimationGroup()
animationGroup.duration = 1.0
animationGroup.animations = [ arcAnimation, scaleAnimation]*/ self.layer.insertSublayer(arcLayer, above : circleLayer)
self.layer.addAnimation(scaleAnimation, forKey: nil) } // Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
//override func drawRect(rect: CGRect) {
// Drawing code
//} }

调用时:

let circleLabel = kCircleLabel(percent: 0.52, frame: CGRect(x:  (self.view.bounds.width - 100.0) / 2, y: 260, width: 100.0, height: 100.0))

self.view.addSubview(circleLabel)

要实现这个效果的关键是要学会怎么使用贝塞尔曲线,并给Layer设置Path。