Search code examples
iosswiftcore-graphics

Drawing lines on top of CGImage


I am currently trying to develop a drawing app. The problem that I've come across is optimising the app's performance.

I have subclassed an UIView, in which I am detecting user's inputs.

At first I tried to draw all the lines with CoreGraphics in draw(_ rect: CGRect) method but when the number of lines was 10 000+, the lag was very noticeable. So then I thought of creating a CGImage that I would make after every draw(...) cycle and then when the next draw cycle came, I would put just the new lines on top of that CGImage, therefore not drawing ALL previous lines again and saving precious time.

I am registering new lines in touchesBegan() and touchesMoved() methods and then I am calling self.needsDisplay().

This is the code that I am currently using:

var mainImage: CGImage?
var newLines: [Line]

override func draw(_ rect: CGRect) {

    let context = UIGraphicsGetCurrentContext()

    //context?.translateBy(x: 0, y: bounds.height)
    //context?.scaleBy(x: 1, y: -1)

    if let image = mainImage {
        context?.draw(image, in: bounds)
    }

    for line in newLines {
        context?.setStrokeColor(UIColor.black.cgColor)
        context?.setLineWidth(1)

        context?.move(to: line.previousLocation)
        context?.addLine(to: line.location)

        context?.strokePath()
    }
    newLines = []

    mainImage = context?.makeImage()
}

Now the problem with it is that the lines I draw are divided in two parts and are mirrored vertically. (Image split vertically). I have drawn here two continuous lines - one straight line and one curved line. The weird thing is that if I flipped half of the UIView, the lines would be aligned continuously with no space between them.

If I uncommented the two lines from my previously mentioned code (context?.translateBy(x: 0, y: bounds.height) and context?.scaleBy(x: 1, y: -1)), the image would look like this.

The only wrong thing now is that I was drawing on the lower side of the screen and getting results on the upper one.

How do I correct it? What is the proper solution for my problem?

Thank you very much!


Solution

  • When you comment out those two lines, then you are NOT making any changes to the graphics context. If you un-comment them, then you ARE changing the context at each call and not saving it. So I think you're essentially flipping it each time. Not sure if it's that but you should definitely be pushing/saving your context before drawing (and obviously restoring/popping it).

    Check out this post: using UIImage drawInRect still renders it upside down.