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

Mic*_*ael 2 xcode progress-bar swift xcode13

几天前,我想用 swift 创建一个圆形进度条

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

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

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

它看起来像这样:

该代码将非常易于使用。

在此输入图像描述 在此输入图像描述

Mic*_*ael 13

对我来说,找出如何使进度条变圆并不容易。

所以我创建了一个可重用的代码,这样每个人都可以简单地使用它。我创建了一个类。

这是课程:

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()
    
}

}
Run Code Online (Sandbox Code Playgroud)

以下是如何使用:

创建新的进度视图

让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()将轨道颜色设置为进度颜色,但透明度较小。

设置progressView的位置(示例):

ProgressView.center = view.center

您可以使用它,因为 ProgressView 是 UIView 类型。

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

view.addSubview(progressView)

设置progressView的进度:

进度视图.进度 = 0.6

进度将以动画形式显示。如果您不想为进度设置动画,可以将ProgressView.timeToFill设置为 0。如果您想要更快或更低的动画,也可以使用此方法。

我希望这段代码有帮助。