封裝一個UILabel圓形邊框顯示進度

封裝了一個UILabel並讓它顯示圓形的邊框,UILabel上面顯示百份比,而邊框則用Animation繪製到整個圓佔指定百分比的點。ide

                                                               

這只是我我的想的繼承一個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
    //}
    

}

 調用時:ui

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

 self.view.addSubview(circleLabel)orm

 要實現這個效果的關鍵是要學會怎麼使用貝塞爾曲線,並給Layer設置Path。blog

相關文章
相關標籤/搜索