如何让Circular Progress View的描边从红色圆圈外侧开始?
解决圆形进度条描边从外侧起始的问题
问题原因
CAShapeLayer的描边默认是沿路径居中绘制,你当前的描边路径与红色填充路径重合,导致描边一半落在红色圆内部,一半在外部,无法实现描边完全在外侧的需求。
解决方案
通过分离红色填充层与描边层路径,计算正确的描边路径半径,让描边整体位于红色圆外侧:
- 为红色实心圆创建单独图层,确保它处于最底层;
- 对每个描边图层(灰色轨迹、绿色进度),设置路径半径为「红色圆半径 + 该图层线宽的一半」,这样描边的内边缘刚好与红色圆外边缘对齐,整个描边都在外侧;
- 修正图层顺序,保证显示层级正确。
修改后的完整代码
var progressLayer = CAShapeLayer() var trackLayer = CAShapeLayer() var fillLayer = CAShapeLayer() // 新增红色填充专用图层 var progressLineWidth: CGFloat = 20 var progressColor = UIColor.green var progress: Float = 0.5 let trackLineWidth: CGFloat = 10 // 红色实心圆:居中绘制,作为底层 let fillRadius = frame.size.width / 2 let fillPath = UIBezierPath(arcCenter: CGPoint(x: frame.midX, y: frame.midY), radius: fillRadius, startAngle: 0, endAngle: .pi * 2, clockwise: true) fillLayer.path = fillPath.cgPath fillLayer.fillColor = UIColor.red.cgColor layer.addSublayer(fillLayer) // 灰色轨迹描边:路径半径 = 红色圆半径 + 轨迹线宽的一半 let trackRadius = fillRadius + trackLineWidth / 2 let trackPath = UIBezierPath(arcCenter: CGPoint(x: frame.midX, y: frame.midY), radius: trackRadius, startAngle: -(.pi / 2), endAngle: .pi * 1.5, clockwise: true) trackLayer.path = trackPath.cgPath trackLayer.strokeColor = UIColor.gray.cgColor trackLayer.lineWidth = trackLineWidth trackLayer.strokeEnd = 1.0 trackLayer.lineDashPattern = [4,4] trackLayer.fillColor = UIColor.clear.cgColor layer.addSublayer(trackLayer) // 绿色进度描边:路径半径 = 红色圆半径 + 进度线宽的一半 let progressRadius = fillRadius + progressLineWidth / 2 let progressPath = UIBezierPath(arcCenter: CGPoint(x: frame.midX, y: frame.midY), radius: progressRadius, startAngle: -(.pi / 2), endAngle: .pi * 1.5, clockwise: true) progressLayer.path = progressPath.cgPath progressLayer.fillColor = UIColor.clear.cgColor progressLayer.strokeColor = progressColor.cgColor progressLayer.lineWidth = progressLineWidth progressLayer.strokeEnd = CGFloat(progress) progressLayer.strokeStart = 0 progressLayer.lineDashPattern = [4,4] layer.addSublayer(progressLayer)
额外说明
- 如果希望灰色轨迹和绿色进度共用同一个外侧环,需要将两者的
lineWidth设置为相同值,或者统一路径半径为「红色圆半径 + 最大线宽的一半」,根据需求调整即可; - 移除了原代码中
arcCenter的偏移量,确保所有图层居中对齐,避免显示错位。
内容的提问来源于stack exchange,提问作者Tolgay Toklar
相关产品推荐
相关产品推荐

