I have a very simple application. Which draws lines when you touch the screen with two fingers, when they lift their fingers I want to erase the drawing, and when they draw again show new lines.
However, when I delete the lines the first time, the next press causes an error with no error message. I figure I'm doing something small wrong, but I can't figure it out. Here is my code:
var prevX: CGFloat!
var prevY: CGFloat!
var startX: CGFloat = 150
var startY : CGFloat = 450
var reset: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
var pan = UIPanGestureRecognizer(target: self, action: "pan:")
pan.cancelsTouchesInView = false
pan.delegate = self
self.view.addGestureRecognizer(pan)
}
func pan(recognizer:UIPanGestureRecognizer) {
print(self.view.layer)
var state = recognizer.state
if (state == UIGestureRecognizerState.Ended) {
reset = true
var sublayers = self.view.layer.sublayers
for layer in sublayers {
layer.removeFromSuperlayer()
}
} else {
var interval = recognizer.translationInView(self.view)
if (reset) {
reset = false
prevX = CGFloat(startX + interval.x)
prevY = CGFloat(startY + interval.y)
}
var newPointX = startX + interval.x
var newPointY = startY + interval.y
var path = UIBezierPath().bezierPathByReversingPath()
path.moveToPoint(CGPoint(x: prevX, y: prevY))
path.addLineToPoint(CGPoint(x:newPointX, y:newPointY))
var shapeLayer = CAShapeLayer()
shapeLayer.path = path.CGPath
shapeLayer.strokeColor = UIColor.blueColor().CGColor
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = UIColor.clearColor().CGColor
self.view.layer.addSublayer(shapeLayer)
prevX = newPointX
prevY = newPointY
}
}
A little more information about the error
Thread 1: EXC_BAD_ACCESS code=1, address=0x499e....
___UIApplicationExtensionGetAccurateShareServicesExtensionForIdentifier_block_invoke_2
0x18c00e3c0: adrp x8, 54568
0x18c00e3c4: ldr x8, [x8, #2248]
0x18c00e3c8: ldr x8, [x8]
0x18c00e3cc: ldr x9, [sp, #56]
0x18c00e3d0: sub x8, x8, x9
0x18c00e3d4: cbnz x8, 0x18c00e3fc ; UIApplicationMain + 1548
0x18c00e3d8: movz w0, #0
I think it is this line that is causing the error.
for layer in sublayers {
layer.removeFromSuperlayer()
}
because if I remove it the program works without any problem ( but it doesn't delete the lines )
The problem is because you are modifying the size of the Array of layers directly. To fix it, add the following variable:
Then, every time you "paint" a line, save it in that variable:
And finally:
With this you will no longer have problems.
What you can do is create a subclass of
CAShapeLayer
and use that subclass. So when you go to delete the lines, you can do a pre-check like this:This should work for you.