如何在 swift 中制作圆形或填充和圆形进度视图 swift(使用 CAShapeLayers)

How to make a rounded or filled and rounded progress view swift in swift (with CAShapeLayers)

前几天想在swift

中做一个圆角进度条

我看了很多视频并用谷歌搜索了很多。

在大多数情况下,代码无法正常工作,因为它太复杂而难以理解。几天后我明白了。

我想,一定有更简单的方法,所以在这里创建了这段代码。

看起来像这样:

该代码将非常易于使用。

我发现如何使进度条变圆并不容易。

所以我创建了一个可重用的代码,让大家可以简单地使用它。我创建了一个 class.

这里是 class:

import UIKit

class CircularProgressView: UIView {

fileprivate var progressLayer = CAShapeLayer()
fileprivate var trackLayer = CAShapeLayer()
fileprivate var didConfigureLabel = false
fileprivate var rounded: Bool
fileprivate var filled: Bool


fileprivate let lineWidth: CGFloat?



var timeToFill = 3.43



var progressColor = UIColor.white {
    didSet{
        progressLayer.strokeColor = progressColor.cgColor
    }
}

var trackColor = UIColor.white {
    didSet{
        trackLayer.strokeColor = trackColor.cgColor
    }
}


var progress: Float {
    didSet{
        var pathMoved = progress - oldValue
        if pathMoved < 0{
            pathMoved = 0 - pathMoved
        }
        
        setProgress(duration: timeToFill * Double(pathMoved), to: progress)
    }
}




fileprivate func createProgressView(){
    
    self.backgroundColor = .clear
    self.layer.cornerRadius = frame.size.width / 2
    let circularPath = UIBezierPath(arcCenter: center, radius: frame.width / 2, startAngle: CGFloat(-0.5 * .pi), endAngle: CGFloat(1.5 * .pi), clockwise: true)
    trackLayer.fillColor = UIColor.blue.cgColor
    
    
    trackLayer.path = circularPath.cgPath
    trackLayer.fillColor = .none
    trackLayer.strokeColor = trackColor.cgColor
    if filled {
        trackLayer.lineCap = .butt
        trackLayer.lineWidth = frame.width
    }else{
        trackLayer.lineWidth = lineWidth!
    }
    trackLayer.strokeEnd = 1
    layer.addSublayer(trackLayer)
    
    progressLayer.path = circularPath.cgPath
    progressLayer.fillColor = .none
    progressLayer.strokeColor = progressColor.cgColor
    if filled {
        progressLayer.lineCap = .butt
        progressLayer.lineWidth = frame.width
    }else{
        progressLayer.lineWidth = lineWidth!
    }
    progressLayer.strokeEnd = 0
    if rounded{
        progressLayer.lineCap = .round
    }
    
    
    layer.addSublayer(progressLayer)
    
}





func trackColorToProgressColor() -> Void{
    trackColor = progressColor
    trackColor = UIColor(red: progressColor.cgColor.components![0], green: progressColor.cgColor.components![1], blue: progressColor.cgColor.components![2], alpha: 0.2)
}



func setProgress(duration: TimeInterval = 3, to newProgress: Float) -> Void{
    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.duration = duration
    
    animation.fromValue = progressLayer.strokeEnd
    animation.toValue = newProgress
    
    progressLayer.strokeEnd = CGFloat(newProgress)
    
    progressLayer.add(animation, forKey: "animationProgress")
    
}



override init(frame: CGRect){
    progress = 0
    rounded = true
    filled = false
    lineWidth = 15
    super.init(frame: frame)
    filled = false
    createProgressView()
}

required init?(coder: NSCoder) {
    progress = 0
    rounded = true
    filled = false
    lineWidth = 15
    super.init(coder: coder)
    createProgressView()
    
}


init(frame: CGRect, lineWidth: CGFloat?, rounded: Bool) {
    
    
    progress = 0
    
    if lineWidth == nil{
        self.filled = true
        self.rounded = false
    }else{
        if rounded{
            self.rounded = true
        }else{
            self.rounded = false
        }
        self.filled = false
    }
    self.lineWidth = lineWidth
    
    super.init(frame: frame)
    createProgressView()
    
}

}

下面是使用方法:

创建新的进度视图

let progressView = CircularProgressView(frame: CGRect(x: 0, y: 0, width: 100, height: 100), lineWidth: 15, rounded: false)

如果线宽使用nil,会出现如上图第二个实心圆

设置进度和轨道颜色:

progressView.progressColor = .blue

progressView.trackColor = .lightGray

如果您使用 progressView.trackColorToProgressColor() 将轨道颜色设置为进度颜色,但使用较少的 alpha。

设置progressView的位置(例子):

progressView.center = view.center

你可以使用这个,因为progressView是UIView类型。

将 progressView 添加为 ViewControllers 视图的子视图:

view.addSubview(progressView)

设置progressView的进度:

progressView.progress = 0.6

进度将动画化。如果您不想动画化进度,您可以将 progressView.timeToFill 设置为 0。如果您想要更快或更慢的动画,您也可以使用此方法。

希望这段代码对您有所帮助。