user594883 user594883 - 28 days ago 17
Swift Question

CoreGraphics drawing results to CGContextDrawPath: invalid context 0x0

I'm getting tons of

CGContextDrawPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
errors from this code. It is executed within a SKScene. Basically I'm getting user's drawing on screen as a SKShapeNode. Then I'm populating that drawing's path with circles by Core Graphics. However the code runs slow and gives me tons of errors. I'm sort of new to Swift. Can you help me with what's going on? How can I speed this up? How can I give CoreGraphics proper context?

let boundingBox = createdShape.frame
for j in stride(from: Int(boundingBox.minX), to: Int(boundingBox.maxX), by: 10) {
for i in stride(from: Int(boundingBox.minY), to: Int(boundingBox.maxY), by: 10) {
//for i in 0..<10 {
counter += 1
//let originalPoint = CGPoint(x: ((boundingBox.maxX - boundingBox.minX)/2)+boundingBox.minX, y: (boundingBox.maxY-CGFloat(i*10)))
//let originalPoint = CGPoint(x: CGFloat(j), y: (boundingBox.maxY-CGFloat(i*10)))
let originalPoint = CGPoint(x: CGFloat(j), y: (CGFloat(i)))
let point:CGPoint = self.view!.convert(originalPoint, from: self)

if (createdShape.path?.contains(createdShape.convert(originalPoint, from: self)))! {
let circlePath = UIBezierPath(arcCenter: point, radius: CGFloat(5), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
circlePath.fill()

let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath

shapeLayer.fillColor = UIColor(red: 180/255, green: 180/255, blue: 180/255, alpha: 0.4).cgColor
shapeLayer.strokeColor = UIColor(red: 180/255, green: 180/255, blue: 180/255, alpha: 0.4).cgColor
shapeLayer.lineWidth = 0.0

view!.layer.addSublayer(shapeLayer)
}

}
}

TiM TiM
Answer

Looking at your code, I believe the culprit line of code is:

circlePath.fill()

As UIBezierPath.fill() is a Core Graphics draw operation, it needs to be called within a Core Graphics context in order for it to know where it will actually be drawing.

This is usually done inside UIGraphicsBeginImageContextWithOptions() / UIGraphicsEndImageContext() where you explicitly create and end a context, or in certain UIKit methods like UIView.drawRect() where the context is automatically managed for you.

From the looks of it, calling fill() in that part of your code is being done outside of a context being present, which is why it's reporting an invalid context of 0x0.

In this particular case, it looks like you're using that circlePath object as the clipping mask for a CAShapeLayer, so it's probably not necessary to call fill() there.

Let me know if you need additional clarification. :)