ImageRenderer renders a SwiftUI view hierarchy to a UIImage, a CGImage, or into any
CGContext. Use it to export a chart or a summary section as an image or a PDF page.
Rendering a View
The renderer takes one thing, the content view. It conforms to ObservableObject, so held as a
@StateObject it refreshes the body when the rendered image becomes available.
struct ContentView: View {
@StateObject private var renderer = ImageRenderer(
content: MyChartView(numbers: [1, 2, 3])
)
var body: some View {
if let image = renderer.uiImage {
Image(uiImage: image)
}
}
}
Exporting at Runtime
For dynamic content, create the renderer on demand, for example in a toolbar action. Set
renderer.scale from the environment's displayScale, or the export comes out at 1x and looks
blurry on the device. proposedSize and colorMode tune the output the same way.
struct SummaryContainerView: View {
@State private var image: UIImage?
@Environment(\.displayScale) private var scale
var body: some View {
List { summarySection }
.toolbar {
Button("Export") {
let renderer = ImageRenderer(content: summarySection)
renderer.scale = scale
image = renderer.uiImage
}
}
}
private var summarySection: some View {
Section { /* ... */ }
}
}
The content does not have to be a whole screen: any view value, such as one section, renders on its own.
Rendering into a PDF
The render function hands you the content size and a closure that draws into a CGContext,
which is how a SwiftUI view becomes a PDF page.
let renderer = ImageRenderer(content: summarySection)
renderer.render { size, renderInContext in
var box = CGRect(origin: .zero, size: .init(width: 600, height: 800))
guard let context = CGContext(fileUrl as CFURL, mediaBox: &box, nil) else { return }
context.beginPDFPage(nil)
renderInContext(context)
context.endPage()
context.closePDF()
}