Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't my UIGraphicsImageRenderer drawing (iOS 10)?

UIGraphicsImageRenderer is the new iOS 10 way to create an image context and draw into it. I'm trying to use UIGraphicsImageRenderer to draw a simple image:

let size = CGSize(width:100,height:100)
let f = UIGraphicsImageRendererFormat()
f.opaque = false
let r = UIGraphicsImageRenderer(size:size, format: f)
let im = r.image { _ in
    let p = UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: size))
    UIColor.blue().setFill()
    p.fill()
}
let iv = UIImageView(image:im)
iv.frame.origin = CGPoint(x: 200, y: 200)
self.view.addSubview(iv)

I expect to see a blue filled circle. But I don't see anything. What am I doing wrong?

PS I'm using Xcode 8 Seed 3, if it matters.

like image 864
matt Avatar asked Jul 23 '16 14:07

matt


People also ask

Is uigraphicsimagerenderer the next big innovation for drawing images on iOS?

We’ve experienced a similar shift on iOS starting with iOS 10, though many engineers have yet to discover or adopt the latest innovation for drawing images — UIGraphicsImageRenderer. Core Graphics, based on the Quartz drawing engine, has provided iOS developers with lightweight 2D rendering capabilities since iOS 2.

What is uigraphicsimagerenderer?

In contrast, UIGraphicsImageRenderer is built for tomorrow in mind: It’s automagically fully color managed. For example, on the beautiful 9.7 inch iPad pro you’ll get a wide color context. It’s a first class object.

What if I don't provide a format for the image?

If you don't provide a format, the default () format is used, which creates a context best suited for the current device. Use the image (actions:) method to create an image ( UIImage object) with an image renderer. This method takes a closure that represents the drawing actions.

How is uigraphicsimagerenderer different from core graphics?

Though Swift’s syntactical sugar prowess has softened the call sites to Core Graphics code over many projects, it still is what it is — a C based API built for simpler times. In contrast, UIGraphicsImageRenderer is built for tomorrow in mind: It’s automagically fully color managed.


1 Answers

The problem is that that's not how you make a UIGraphicsImageRendererFormat. The documentation is a bit unclear on this point, but in fact you should be saying this:

let size = CGSize(width:100,height:100)
let f = UIGraphicsImageRendererFormat.default() // *
f.opaque = false
let r = UIGraphicsImageRenderer(size:size, format: f)
let im = r.image { _ in
    let p = UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: size))
    UIColor.blue().setFill()
    p.fill()
}
let iv = UIImageView(image:im)
iv.frame.origin = CGPoint(x: 200, y: 200)
self.view.addSubview(iv)

Your code will then work perfectly.

The problem with the previous code is that UIGraphicsImageRendererFormat() creates a completely unconfigured UIGraphicsImageRendererFormat, which is thus pretty much useless (unless you set all of its properties yourself).

like image 132
matt Avatar answered Sep 27 '22 16:09

matt