如何在 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。如果您想要更快或更慢的动画,您也可以使用此方法。
希望这段代码对您有所帮助。
前几天想在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。如果您想要更快或更慢的动画,您也可以使用此方法。
希望这段代码对您有所帮助。