使用 CAShapeLayer 和 removeFromSuperLayer

Using CAShapeLayer and removeFromSuperLayer

我正在制作一个应用程序,它应该从触摸点绘制对象。

我正在使用 CAShapeLayerUIBezierPath,但是当我使用 removeFromSuperlayer() 时没有任何反应。

我需要删除旧形状并只绘制新形状。

我不知道为什么,但是在构建并上传这个应用程序到我的 iPad 之后,Xcode 给我一个错误:

Cannot use optional chaining on non-optional value of type CAShapeLayer

谁能帮帮我?

另一个问题是:

如何只画一条线?

当我有 2 个点时,它不绘制任何东西,应用程序只在 3 个点或更多点后绘制对象。

这是我的部分代码:

private func drawObj(){

    let objectPath = UIBezierPath()

    objectPath.move(to: CGPoint(x: pointsX[0], y: pointsY[0]))

    let xx = pointsX.count - 1
    print(xx)

    for i in 1...xx {
        objectPath.addLine(to: CGPoint(x: pointsX[i], y: pointsY[i]))
    }

    objectPath.close()

    let object = CAShapeLayer()
    object.removeFromSuperlayer()
    object.path = objectPath.cgPath
    object.fillColor = UIColor.red.cgColor
    object.opacity = 0.2
    self.view.layer.addSublayer(object)
}

如果您创建一个新的 CAShapeLayer,则在该层上调用 removeFromSuperlayer 没有任何意义。您只对先前已添加为其他图层的子图层的图层执行此操作。因此,不要使用您刚刚创建的这个新图层调用 removeFromSuperlayer,而是保存对前一个图层的引用。那是你应该删除的那个。

或者,正如 Dmitry 指出的那样,您应该只添加一次形状层,然后只更新它的路径:

private var shapeLayer: CAShapeLayer = {
    let shapeLayer = CAShapeLayer()
    shapeLayer.fillColor = UIColor.red.cgColor
    shapeLayer.opacity = 0.2
    shapeLayer.strokeColor = UIColor.red.cgColor
    shapeLayer.lineWidth = 1.0
    return shapeLayer
}()

// add this to your view's layer in the logical place, e.g. `viewDidLoad` 

override func viewDidLoad() {
    super.viewDidLoad()

    view.layer.addSublayer(shapeLayer)
}

// now your draw method only needs to update the path

private func drawObj() {
    let objectPath = UIBezierPath()

    objectPath.move(to: CGPoint(x: pointsX[0], y: pointsY[0]))

    for i in 1 ..< pointsX.count {
        objectPath.addLine(to: CGPoint(x: pointsX[i], y: pointsY[i]))
    }

    objectPath.close()

    shapeLayer.path = object.cgPath
}

注意,我还更新了形状层的lineWidthstrokeColor,这样如果只有两个点,没有什么可以"fill",你可以至少看到描边路径。

无需从父图层中删除旧的CAShapeLayer 并插入新的。只需创建一个 CAShapeLayer,将其插入父层即可。然后当你需要更改它时,只需更新它的 'path' 参数即可。