Search code examples
iosuicolorcgcontextuigraphicscontextuigraphicsimagerenderer

How does it know? When UIColor sets fill and UIGraphicsImageRendererContext knows how to fill


I came across an example for using UIGraphicsImageRender to draw in a tutor on Medium. The example code is as follows:

let renderer = UIGraphicsImageRenderer(size: CGSize(width: 20, height: 20))
let img = renderer.image { (ctx) in
    let size = renderer.format.bounds.size
    UIColor.red.setFill()
    ctx.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
}

In the above code, UIColor.red.setFill() apparently only makes the specified colour, i.e. red, ready to fill up a certain shape. However, magically, the ctx, which is a UIGraphicsImageRendererContext, seems to have received a notification that it will fill up the CGRect shape with the red colour!

Purely from the code here, I cannot see the connection between the UIColor instance method setFill() and the UIGraphicsImageRendererContext instance method fill(_: CGRect). So, how does it know? How does UIGraphicsImageRendererContext fills when UIColor sets fill?

Thank you.


Solution

  • Purely from the code here, I cannot see the connection between the UIColor instance method setFill() and the UIGraphicsImageRendererContext

    It knows because you are in the graphics context when you say setFill().

    At every moment when your code is running, there either is or is not a current graphics context. At the time that the image closure of a graphics image renderer runs, there is one — the graphics context that will be used to form the image. That is what it means to be in the image closure.

    Therefore this and similar UIColor and UIBezierPath commands that are (implicitly) directed at the current graphics context will succeed if given in this closure. They would also succeed in, say, a UIView draw(_:) override, because at that moment the view's own graphics context is current.

    Try saying setFill() at some other time, though, and you will see a message complaining that there is no current graphics context.