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.
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.
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.
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With