无法获取 Swift UIBezierPath 图以删除然后更新

Can't get Swift UIBezierPath plot to remove and then update

在我的应用程序中,viewdidLoad() 使用 UIBezierPath 显示绿色 UIBezierPath 标绘线。
但是在程序的后面,事件回调使用相同的 UIBezierPath 来删除所有点并在绿线旁边显示红线。
但是,它所做的只是在同一位置将绿线变成红色。

最终,我想用UIBezierPath来每秒显示一个不断变化的多线图-- 即:删除以前的多线图并每秒显示更新的多线图。

显示绿线的代码................................

    var sensor_plot_UIBezierPath = UIBezierPath()
var sensor_plot_CAShapeLayer = CAShapeLayer()

override func viewDidLoad() 
{
                sensor_plot_UIBezierPath.move(to: CGPoint(  x: 100, 
                                                            y: 100))
                sensor_plot_UIBezierPath.addLine( to: CGPoint(  x:  200,
                                                                y:  200 ) )
        init_app_display()

        ...start background events...
}

func init_app_display()
{
    sensor_plot_CAShapeLayer.path = sensor_plot_UIBezierPath.cgPath
    sensor_plot_CAShapeLayer.fillColor = UIColor.clear.cgColor       // doesn't matter
    sensor_plot_CAShapeLayer.strokeColor = UIColor.green.cgColor
    sensor_plot_CAShapeLayer.lineWidth = 3.0

    view.layer.addSublayer( sensor_plot_CAShapeLayer )
}

应该在其旁边显示红线的代码......
(但实际上在同一位置将初始绿线变为红色 - 第一行旁边没有第二行)

...display_plot_update() is called by event from background thread (specifically, BLE event didUpdateValueFor)

    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 ) )
            self.sensor_plot_CAShapeLayer.strokeColor = UIColor.red.cgColor
        }
    }

与其尝试从路径中删除所有点并重新使用路径对象,不如构造一条新路径。

一旦绘制了路径,它就是上下文的一部分,您不能通过更改路径来删除或更改图形。如果你想从绘图中删除一些东西,你必须删除上下文(或其中的一部分)并在你删除的地方重新绘制。

通常你会擦除所有内容并重新绘制如果。

您也不应该在 viewDidLoad 中绘图,此时视图甚至可能未连接到绘图表面。绘图应该由视图完成,而不是视图控制器。

您没有显示在形状层中安装路径的代码,也没有显示将形状层安装为视图控制器视图的子层的代码。您应该显示该代码,以便我们可以看到您在做什么。您还应该显示 init_app_display() 函数的代码。

我假设您在某处有这样的代码:

sensor_plot_CAShapeLayer.path = self.sensor_plot_UIBezierPath.cgPath

以及类似

的代码
view.layer.addSublayer(sensor_plot_CAShapeLayer)

您似乎认为将 CAShapeLayer 的路径设置为特定的贝塞尔曲线路径会将形状层链接到该路径,并且更新路径会更新形状层。它不是那样工作的。更改路径后,您需要将新路径安装到形状图层中。

您可以像这样更改 display_plot_update() 函数:

func display_plot_update()
{
    DispatchQueue.main.async
    {
        // Create a new bezier path.
        let newPath = UIBezierPath()
        newPath.move(to: CGPoint(     x: 110, 
                                      y: 100))
        newPath.addLine( to: CGPoint( x: 210,
                                      y: 200 ) )
        self.sensor_plot_CAShapeLayer.strokeColor = UIColor.red.cgColor
        self.sensor_plot_CAShapeLayer.path = newPath.cgPath // The important part
    }
}

这会将线移动到您的新坐标并使其变为红色。

如果你想在第一行之后添加第二行,那么写你的 `display_plot_update()~ 函数如下:

func display_plot_update()
{
    DispatchQueue.main.async
    {
        // Add the new line to the existing path (without clearing it)
        self.sensor_plot_UIBezierPath.move(to: CGPoint(     x: 110, 
                                      y: 100))
        self.sensor_plot_UIBezierPath.addLine( to: CGPoint( x: 210,
                                      y: 200 ) )
        self.sensor_plot_CAShapeLayer.strokeColor = UIColor.red.cgColor
        sensor_plot_CAShapeLayer.path = self.sensor_plot_UIBezierPath.cgPath // The important part
    }
}

请注意,单个形状图层中不能有不同颜色的线条。形状图层只能包含一条路径,它使用一种笔触颜色和一种填充颜色绘制整个路径。 (笔触颜色和填充颜色可以不同,但​​整个路径将使用相同的颜色。)