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

Swift使用UIBezierPath绘制路径无法移除旧内容后更新新路径问题

问题根因
  • CAShapeLayer的path是拷贝属性,你初始化时把BezierPath的CGPath赋值给Layer后,后续修改原始的UIBezierPath不会自动同步到Layer上,你只修改了Layer的描边颜色,没有把新的路径赋值给Layer,所以只会看到旧路径变颜色,不会出现新路径
  • 如果你需要同时展示多根不同颜色的折线,单个CAShapeLayer无法实现,同个Layer只能指定一个描边颜色,所有路径都会共用这个颜色
最终需求实现方案

你的需求是每秒清空上一次的所有折线,重新绘制更新后的多折线图表,可按以下逻辑实现:

  • 如果所有折线用同一颜色,所有折线点可以添加到同一个UIBezierPath中,每秒清空路径后添加新的所有折线点,再重新赋值给Layer即可
  • 如果需要不同颜色的折线,为每种颜色提前创建对应的CAShapeLayer和UIBezierPath,每秒更新时分别修改对应路径再同步到Layer

修复当前代码bug示例

你只需要新增路径赋值的步骤即可看到新的红色线条:

func display_plot_update()
{
    DispatchQueue.main.async
    {
        self.sensor_plot_UIBezierPath.removeAllPoints()
        self.sensor_plot_UIBezierPath.move(to: CGPoint(     x: 110, 
                                                            y: 100))
        self.sensor_plot_UIBezierPath.addLine( to: CGPoint(  x:  210,
                                                             y:  200 ) )
        // 新增关键步骤:把更新后的路径同步到ShapeLayer
        self.sensor_plot_CAShapeLayer.path = self.sensor_plot_UIBezierPath.cgPath
        self.sensor_plot_CAShapeLayer.strokeColor = UIColor.red.cgColor
    }
}

同时保留绿线+新增红线的实现示例

新增独立的Layer和路径即可:

// 提前声明红线对应的路径和Layer
var red_plot_UIBezierPath = UIBezierPath()
var red_plot_CAShapeLayer = CAShapeLayer()

func init_red_line_layer() {
    red_plot_CAShapeLayer.fillColor = UIColor.clear.cgColor
    red_plot_CAShapeLayer.strokeColor = UIColor.red.cgColor
    red_plot_CAShapeLayer.lineWidth = 3.0
    view.layer.addSublayer(red_plot_CAShapeLayer)
}

func display_plot_update()
{
    DispatchQueue.main.async
    {
        self.red_plot_UIBezierPath.removeAllPoints()
        self.red_plot_UIBezierPath.move(to: CGPoint( x: 110, y: 100))
        self.red_plot_UIBezierPath.addLine( to: CGPoint( x: 210, y: 200 ) )
        self.red_plot_CAShapeLayer.path = self.red_plot_UIBezierPath.cgPath
    }
}

性能优化注意点

  • 不要每次刷新都重复创建CAShapeLayer,提前创建好所有需要的Layer添加到视图上,更新时仅修改path属性即可,避免多余的性能开销
  • 所有图层相关操作必须在主线程执行,你当前使用DispatchQueue.main.async包裹的写法是正确的
  • 如果折线数据量很大,可以开启CAShapeLayer的shouldRasterize属性做光栅化优化,或者直接用CoreGraphics绘制到UIView的draw方法中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:36:00