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

Swift中使用Bezier Path绘制日期关联进度圆的角度问题

解决自定义TableViewCell进度圆角度不匹配的问题

Hey,我帮你排查了下代码,核心问题出在角度计算的比例逻辑错误——你硬写了* 0.1这个固定系数,这只有当你默认最大间隔天数是10的时候才会凑效,但完全不符合你“date1越接近date2,圆越完整,间隔0天显示满圆”的需求。咱们一步步来修正:

先理清楚你的需求逻辑

你要的效果是:

  • 当date1和date2间隔天数为0(同一天)→ 显示完整的360度圆
  • 当date1和date2间隔天数越多 → 圆的填充进度越少

那正确的进度比例应该是:进度 = 1 - (当前间隔天数 / 你预设的最大间隔天数)。这里的“最大间隔天数”需要根据你的业务场景来定,比如如果是一个30天的任务周期,那最大间隔天数就是30——当间隔天数达到30时,圆完全空着;间隔0天时,圆完全填满。

修正后的代码实现

首先要改掉硬编码的系数,同时处理强制解包的风险,还要解决cell复用导致的图层叠加问题:

// 先安全获取间隔天数,别用强制解包,容易崩
guard let intervalDays = components.day else {
    // 如果获取不到间隔天数,直接显示空圆或者做其他处理
    return
}

// 这里替换成你的业务场景中的最大间隔天数,比如30天
let totalDays = 30

// 计算进度比例:确保比例不会小于0(比如间隔天数超过总天数时,显示0进度)
let progressRatio = max(0.0, 1.0 - Double(intervalDays)/Double(totalDays))

// 角度计算:从12点钟方向(-π/2)开始,顺时针绘制对应比例的圆弧
let startAngle = CGFloat(-Double.pi/2)
let endAngle = startAngle + CGFloat(2 * Double.pi * progressRatio)

// 创建圆弧路径
let circlePath = UIBezierPath(
    arcCenter: CGPoint(x: 80, y: 80),
    radius: 60,
    startAngle: startAngle,
    endAngle: endAngle,
    clockwise: true
)

// 创建形状图层
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.green.cgColor
shapeLayer.lineWidth = 10.0

// 重点:TableViewCell复用的时候,要先移除旧的形状图层,不然会叠加
cell.progressView.layer.sublayers?.filter { $0 is CAShapeLayer }.forEach { $0.removeFromSuperlayer() }
cell.progressView.layer.addSublayer(shapeLayer)

额外优化建议

  1. 动态颜色调整:可以根据进度比例改变描边颜色,让状态更直观:
    let strokeColor: UIColor
    switch progressRatio {
    case ..<0.3:
        strokeColor = .systemRed
    case 0.3..<0.7:
        strokeColor = .systemYellow
    default:
        strokeColor = .systemGreen
    }
    shapeLayer.strokeColor = strokeColor.cgColor
    
  2. 避免硬编码位置和半径:把CGPoint(x:80,y:80)和radius:60改成基于progressView的frame计算,比如arcCenter: CGPoint(x: progressView.bounds.midX, y: progressView.bounds.midY),这样适配不同尺寸的视图更灵活。

为什么你的原代码不对?

原代码里的endAngle = -π/2 + 2π * 间隔天数 * 0.1逻辑完全反了:它是间隔天数越多,圆弧越长,10天的时候才会显示满圆,和你“间隔0天显示满圆”的需求正好相反。而且硬写的0.1没有任何业务依据,只能适配固定10天的场景,完全不通用。

内容的提问来源于stack exchange,提问作者tloz1506996

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:12:18