You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Circular Progress View的描边从红色圆圈外侧开始?

解决圆形进度条描边从外侧起始的问题

问题原因

CAShapeLayer的描边默认是沿路径居中绘制,你当前的描边路径与红色填充路径重合,导致描边一半落在红色圆内部,一半在外部,无法实现描边完全在外侧的需求。

解决方案

通过分离红色填充层与描边层路径,计算正确的描边路径半径,让描边整体位于红色圆外侧:

  1. 为红色实心圆创建单独图层,确保它处于最底层;
  2. 对每个描边图层(灰色轨迹、绿色进度),设置路径半径为「红色圆半径 + 该图层线宽的一半」,这样描边的内边缘刚好与红色圆外边缘对齐,整个描边都在外侧;
  3. 修正图层顺序,保证显示层级正确。

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:27:45