使用 CAShapeLayer 和 removeFromSuperLayer
Using CAShapeLayer and removeFromSuperLayer
我正在制作一个应用程序,它应该从触摸点绘制对象。
我正在使用 CAShapeLayer
和 UIBezierPath
,但是当我使用 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
}
注意,我还更新了形状层的lineWidth
和strokeColor
,这样如果只有两个点,没有什么可以"fill",你可以至少看到描边路径。
无需从父图层中删除旧的CAShapeLayer 并插入新的。只需创建一个 CAShapeLayer,将其插入父层即可。然后当你需要更改它时,只需更新它的 'path' 参数即可。
我正在制作一个应用程序,它应该从触摸点绘制对象。
我正在使用 CAShapeLayer
和 UIBezierPath
,但是当我使用 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
}
注意,我还更新了形状层的lineWidth
和strokeColor
,这样如果只有两个点,没有什么可以"fill",你可以至少看到描边路径。
无需从父图层中删除旧的CAShapeLayer 并插入新的。只需创建一个 CAShapeLayer,将其插入父层即可。然后当你需要更改它时,只需更新它的 'path' 参数即可。