I have a CGPath drawn in a custom UIView as follows. There is a refresh button that is supposed to add new line to the path already drawn.
private func refresh() {
self.setNeedsDisplay()
}
override func draw(_ rect: CGRect){
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.setLineWidth(1)
context.addPath(self.newPathPart())
context.setStrokeColor(UIColor.white.cgColor)
context.interpolationQuality = .none
context.setAllowsAntialiasing(false)
context.setShouldAntialias(false)
context.strokePath()
}
private func newPathPart() -> CGPath {
let lineWidth: CGFloat = 1
let mPath = CGMutablePath()
if lastPoint == nil {
lastPoint = CGPoint(x: self.bounds.midX - lineWidth/2, y: self.bounds.midY - lineWidth/2)
}
mPath.move(to: lastPoint!)
mPath.addLine(to: CGPoint(x: lastPoint!.x + 15, y: lastPoint!.y + 15))
lastPoint = CGPoint(x: lastPoint!.x + 15, y: lastPoint!.y + 15)
mPath.closeSubpath()
return mPath
}
I had an impression that the newPartPath() will be appended to existing path that is drawn but that seems not to be the case. I wish to optimise the code so that I do not completely redraw the whole path on every refresh, but just the path that is added. How do I achieve it?
You need to keep on hand a CGMutablePath, or a collection of CGPaths, so that you can keep accumulating new path parts in an actual CGPath.
When draw
is called, it has a rect
. You are ignoring that parameter. Don't ignore it. You only need to supply the part of the drawing that is in that rect
. So examine the rect
and draw in such a way as to supply the missing part of the drawing that does into it. In other words, you draw just the parts of your path that intersect that rect
.
Note that if you are the one responsible for knowing that there is a new part of the path waiting to be drawn, you can call setNeedsDisplay(in:)
with the rect
of that part of the path, so that that is the rect
that is asked for in draw
.