自定義環形進度條UIAnnularProgress(Swift)

很多地方都會使用環形進度條,這裏我們就繼承自UIView,自定義一個環形進度條控件,可以設置進度條顏色,寬度,進度,動畫效果。

我們自定義一個環型圖層添加到UIView的圖層上去,從而實現環形控件。我們使用CAShapeLayer類創建自己的圖層。它有幾個常用的屬性:frame 尺寸,fillColor圖層填充色,strokeColor圖層邊界的顏色,lineWidth 邊界線寬,path 圖層路徑通過這個路徑我們可以控制圖層的形狀在這裏我們會給圖層一個圓形路徑讓整個視圖呈現環狀,strokeStart簡單點理解就是繪製的起點在這我們把它作爲初始進度,strokeEnd繪製的終點它可以作爲結束的進度。
我們先創建一個圖層,完全繪製作爲進度條的底部圖形:

 let path = UIBezierPath(ovalInRect: bounds).CGPath       
 let trackLayer = CAShapeLayer()
 trackLayer.frame = bounds
 trackLayer.fillColor = UIColor.clearColor().CGColor
 trackLayer.strokeColor = progressProperty.trackColor.CGColor
 trackLayer.lineWidth = progressProperty.width
 trackLayer.path = path
 layer.addSublayer(trackLayer)
let path = UIBezierPath(ovalInRect: bounds).CGPath //這是我們以視圖尺寸創建的一個內切圓,將這個圓作爲路徑。

接下來我們再創建一個圖層,表示進度條視圖的進度,並且給這個圖層一個初始的進度

        progressLayer.frame = bounds
        progressLayer.fillColor = UIColor.clearColor().CGColor
        progressLayer.strokeColor = progressProperty.progressColor.CGColor
        progressLayer.lineWidth = progressProperty.width
        progressLayer.path = path
        progressLayer.strokeStart = progressProperty.progressStart
        progressLayer.strokeEnd = progressProperty.progressEnd
        layer.addSublayer(progressLayer)

最後我們給表示進度的圖層添加動畫屬性,使用CATransaction動畫:

 CATransaction.begin()
        CATransaction.setDisableActions(!animate)
        CATransaction.setAnimationDuration(time)
        CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut))
        progressLayer.strokeEnd = progress
        CATransaction.commit()

下面我們在控制器裏面使用這個自定義控件創建兩個進度條進行測試體驗效果:

    var progressView1:UIAnnularProgress?
    var progressView2:UIAnnularProgress?
    var progress:CGFloat?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        progress = 0.25

        progressView1 = UIAnnularProgress(propressProperty:ProgressProperty(width: 5, progressEnd: 0.1, progressColor: UIColor.redColor()), frame:CGRectMake(50,100,200,200))
        self.view.addSubview(progressView1!)

        progressView2 = UIAnnularProgress(frame: CGRectMake(50,350,150,150))
        self.view.addSubview(progressView2!)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        progress! = progress! + 0.1
        if progress! >= 1.0 {
            progress! = 0
        }
        progressView1?.setProgress(progress!, time:0.6, animate: false)

        progressView2?.setProgress(progress!, time:0.6, animate: true)

    }

以下是自定義進度條控件的源碼:

//
//  UIAnnularProgress.swift
//  環形進度條
//
//  Created by 句芒 on 16/9/26.
//  Copyright © 2016年 fanwei. All rights reserved.
//

import UIKit


struct ProgressProperty{
    var width:CGFloat
    var trackColor:UIColor
    var progressColor :UIColor
    var progressStart:CGFloat
    var progressEnd:CGFloat

    init(width:CGFloat,progressEnd:CGFloat,progressColor:UIColor) {
        self.width = width
        self.progressEnd = progressEnd
        self.progressColor = progressColor
        trackColor = UIColor.grayColor()
        progressStart = 0.0
    }

    init() {
        width = 10
        trackColor = UIColor.grayColor()
        progressColor = UIColor.greenColor()
        progressStart = 0.0
        progressEnd = 0.25
    }
}



class UIAnnularProgress: UIView {

    var progressProperty = ProgressProperty.init()
    private let progressLayer = CAShapeLayer()

    init(propressProperty:ProgressProperty,frame:CGRect) {
        self.progressProperty = propressProperty
        super.init(frame: frame)
        self.backgroundColor = UIColor.clearColor()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.clearColor()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func drawRect(rect: CGRect) {
        let path = UIBezierPath(ovalInRect: bounds).CGPath

        let trackLayer = CAShapeLayer()
        trackLayer.frame = bounds
        trackLayer.fillColor = UIColor.clearColor().CGColor
        trackLayer.strokeColor = progressProperty.trackColor.CGColor
        trackLayer.lineWidth = progressProperty.width
        trackLayer.path = path
        layer.addSublayer(trackLayer)

        progressLayer.frame = bounds
        progressLayer.fillColor = UIColor.clearColor().CGColor
        progressLayer.strokeColor = progressProperty.progressColor.CGColor
        progressLayer.lineWidth = progressProperty.width
        progressLayer.path = path
        progressLayer.strokeStart = progressProperty.progressStart
        progressLayer.strokeEnd = progressProperty.progressEnd
        layer.addSublayer(progressLayer)

    }

    func setProgress(progress:CGFloat,time:CFTimeInterval,animate:Bool) {
        CATransaction.begin()
        CATransaction.setDisableActions(!animate)
        CATransaction.setAnimationDuration(time)
        CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut))
        progressLayer.strokeEnd = progress
        CATransaction.commit()

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章