Skip to content

ImageRenderer (SwiftUI)

A SwiftUI guide for coding agents. Also covers export view as image, render swiftui to uiimage, save chart as image, swiftui view to pdf, displayscale export, cgcontext render.

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()
}

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-imagerenderer" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems