Reputation: 90
I am freehand drawing a UIBezierPath but now I want to be able to erase the lines I previously drawn. Does anyone have any suggestions on how to do that?
@objc private func didPanWhiteboard(_ gesture: UIPanGestureRecognizer) {
let location = gesture.location(in: drawCanvasView)
switch gesture.state {
case .began:
path = UIBezierPath()
path.move(to: location)
strokeLayer = CAShapeLayer()
drawCanvasView.layer.addSublayer(strokeLayer)
path.stroke(with: shouldErase ? .clear : .normal, alpha: 1.0)
strokeLayer.strokeColor = toolColor.cgColor
strokeLayer.fillColor = UIColor.clear.cgColor
strokeLayer.lineWidth = toolWidth
strokeLayer.path = path?.cgPath
case .changed:
path.addLine(to: location)
strokeLayer.path = path.cgPath
case .cancelled, .ended: drawLayers.append(strokeLayer)
default: break
}
}
this is how I draw the lines and so far for erasing I tried:
path.stroke(with: shouldErase ? .clear : .normal, alpha: 1.0)
but it dosen't seem to do anything when shouldErase is true.
EDIT: this is what I'd like to achieve:
https://i.sstatic.net/gMXsE.jpg
Feel free to suggest any kind of approach.
Upvotes: 0
Views: 581
Reputation: 90
I managed to solve this using CGContext
.
@objc private func didPanWhiteboard(_ gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
drawingState = .began
lastPoint = gesture.location(in: drawingBoardImageView)
case .changed:
drawingState = .moved
let currentPoint = gesture.location(in: drawingBoardImageView)
drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)
lastPoint = currentPoint
case .cancelled, .ended:
drawingState = .ended
drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
default: break
}
}
private func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
UIGraphicsBeginImageContext(drawingBoardImageView.frame.size)
let context = UIGraphicsGetCurrentContext()
tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: drawingBoardImageView.frame.size.width, height: drawingBoardImageView.frame.size.height))
context?.move(to: fromPoint)
context?.addLine(to: toPoint)
context?.setLineCap(brush.lineCap)
context?.setAlpha(brush.opacity)
context?.setLineWidth(brush.width)
context?.setStrokeColor(brush.color.cgColor)
if shouldErase {
context?.setBlendMode(.clear)
} else {
context?.setBlendMode(.normal)
}
context?.strokePath()
guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }
if drawingState == .ended {
drawingUndoManager.registerForUndo(image)
}
tempImageView.image = image
tempImageView.alpha = 1.0
UIGraphicsEndImageContext()
}
Upvotes: 2