我想画一个进度条的如下部分:
用我的代码到目前为止,我可以画半圈的条纹,但我不能让条纹停止在1/3的圆圈,他们去所有的方式结束。另外,我如何添加白色背景?以下是我目前的代码:
class HalfCircleProgressView: UIView {
var progress: CGFloat = 0.0 {
didSet {
setNeedsDisplay()
}
}
private let backgroundLayerOne = CAShapeLayer()
override func draw(_ rect: CGRect) {
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2 + 50)
let radius = min(bounds.width + 150, bounds.height + 150) / 2 - 50
let startAngle = Double.pi
let endAngle = startAngle + progress * CGFloat(Double.pi)
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
path.lineWidth = 15
UIColor.white.setStroke()
path.stroke()
let stripePath = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
stripePath.lineWidth = 15
let dashes: [CGFloat] = [52.5, 2]
stripePath.setLineDash(dashes, count: dashes.count, phase: 0)
UIColor.red.setStroke()
stripePath.stroke()
}
}
这是我当前进度条在进度达到80%时的样子:
1条答案
按热度按时间nafvub8i1#
几个建议...
首先,不要硬编码大小/位置值,而是将
HalfCircleProgressView
保持为2:1
比率,并使弧完全适合视图:然后,您可以将该视图嵌入到“容器”中:
并相对于
HalfCircleProgressView
:并将背景设置为清晰:
接下来,使用
CAShapeLayer
而不是重写draw()
:使用
CAShapeLayer
有几个优点--对于您的特殊需要,最大的优点是我们可以使用.strokeEnd
属性“自动管理”前景弧及其完成的“百分比”。因此,如果背景和前景“arc”图层使用相同的path和lineWidth属性:
当我们想要将红色“进度”弧设置为,比如说,25%时,我们设置:
对于80%:
不需要从百分比计算Angular 和重新绘制一切。
那么,“勾号”是怎么回事?
好吧,看起来你想在(我猜):
我们将使用带有线段的贝塞尔曲线路径作为“刻度线”形状层的
.cgPath
,而不是在前景弧线上使用蒙版图案。形状层路径是“在中线上”描边的,因此我们需要循环“间隙”步骤,计算15点粗弧的“外边缘”上的Angular 点,计算“内边缘”上的Angular 点,然后计算
.move(to:)
和.addLine(to:)
。我们 * 可以 * 为这些计算编写一些数学公式...或者,我们可以***“作弊”***并利用
UIBezierPath
的.currentPoint
属性!当我们像这样操纵路径时:
我们可以得到该弧的“终点”:
因此,为了添加线段,我们将创建半径为
radius PLUS lineWidth * 0.5
的“outerPath”和半径为radius MINUS lineWidth * 0.5
的“innerPath”,然后我们以.addArc
开始每条路径,到第一个刻度的Angular ,并循环七次(7个刻度线)......每次通过循环增加Angular 并添加线段:一直到第7圈:
当然,我们不会看到那些额外的路径:
因此,我们的自定义视图现在在100%时如下所示:
占33%:
占78.27%:
下面是一些可以使用的示例代码:
以及一个示例控制器,其中包含一些“百分比按钮”和一个用于更改“进度”百分比的滑块:
运行时将如下所示: