ImageRenderer
is one other new API for SwiftUI that comes with iOS 16. It permits you to simply convert any SwiftUI views into a picture. The implementation could be very easy. You instantiate an occasion of ImageRenderer
with a view for the conversion:
let renderer = ImageRenderer(content material: theView) |
You’ll be able to then entry the cgImage
or uiImage
property to retrieve the generated picture.
As all the time, I like to show the utilization of an API with an instance. Earlier, we’ve constructed a line chart utilizing the brand new Charts framework. Let’s see methods to let customers save the chart as a picture within the picture album and share it utilizing ShareLink
.
Revisit the Chart View

First, let’s revisit the code of the ChartView instance. We used the brand new API of the Charts
framework to create a line chart and show the climate knowledge. Right here is the code snippet:
.foregroundStyle(by: .worth(“Metropolis”, sequence.metropolis))
.image(by: .worth(“Metropolis”, sequence.metropolis))
.chartXAxis
AxisMarks(values: .stride(by: .month)) worth in
AxisGridLine()
AxisValueLabel(format: .dateTime.month(.defaultDigits))
.chartPlotStyle plotArea in
plotArea
.background(.blue.opacity(0.1))
.chartYAxis
AxisMarks(place: .main)
.body(width: 350, top: 300)
.padding(.horizontal)
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
var physique: some View { VStack Chart ForEach(chartData, id: .metropolis) sequence in ForEach(sequence.knowledge) merchandise in LineMark( x: .worth(“Month”, merchandise.date), y: .worth(“Temp”, merchandise.temperature) )
.foregroundStyle(by: .worth(“Metropolis”, sequence.metropolis)) .image(by: .worth(“Metropolis”, sequence.metropolis))
.chartXAxis AxisMarks(values: .stride(by: .month)) worth in AxisGridLine() AxisValueLabel(format: .dateTime.month(.defaultDigits))
.chartPlotStyle plotArea in plotArea .background(.blue.opacity(0.1))
.chartYAxis AxisMarks(place: .main)
.body(width: 350, top: 300) .padding(.horizontal)
} |
To make use of ImageRenderer
, we first refactor this piece of code right into a separate view like this:
var physique: some View {
VStack
Chart
ForEach(chartData, id: .metropolis) sequence in
ForEach(sequence.knowledge) merchandise in
LineMark(
x: .worth(“Month”, merchandise.date),
y: .worth(“Temp”, merchandise.temperature)
)
.foregroundStyle(by: .worth(“Metropolis”, sequence.metropolis))
.image(by: .worth(“Metropolis”, sequence.metropolis))
.chartXAxis
AxisMarks(values: .stride(by: .month)) worth in
AxisGridLine()
AxisValueLabel(format: .dateTime.month(.defaultDigits))
.chartPlotStyle plotArea in
plotArea
.background(.blue.opacity(0.1))
.chartYAxis
AxisMarks(place: .main)
.body(width: 350, top: 300)
.padding(.horizontal)
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
struct ChartView: View { let chartData = [ (city: “Hong Kong”, data: hkWeatherData), (city: “London”, data: londonWeatherData), (city: “Taipei”, data: taipeiWeatherData) ]
var physique: some View { VStack
Chart ForEach(chartData, id: .metropolis) sequence in ForEach(sequence.knowledge) merchandise in LineMark( x: .worth(“Month”, merchandise.date), y: .worth(“Temp”, merchandise.temperature) )
.foregroundStyle(by: .worth(“Metropolis”, sequence.metropolis)) .image(by: .worth(“Metropolis”, sequence.metropolis))
.chartXAxis AxisMarks(values: .stride(by: .month)) worth in AxisGridLine() AxisValueLabel(format: .dateTime.month(.defaultDigits))
.chartPlotStyle plotArea in plotArea .background(.blue.opacity(0.1))
.chartYAxis AxisMarks(place: .main)
.body(width: 350, top: 300) .padding(.horizontal)
} }
|
Subsequent, we declare a variable to carry the view:
var chartView = ChartView() |
Changing the View into an Picture utilizing ImageRenderer
Now we’re able to convert the chart view into a picture. We’ll add a button named Save to Photographs for saving the chart view picture within the picture album.
Let’s implement the button like this:
VStack(spacing: 20)
chartView
HStack
Button
let renderer = ImageRenderer(content material: chartView)
if let picture = renderer.uiImage
UIImageWriteToSavedPhotosAlbum(picture, nil, nil, nil)
label:
Label(“Save to Photographs”, systemImage: “picture”)
.buttonStyle(.borderedProminent)
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var physique: some View {
VStack(spacing: 20) chartView
HStack Button let renderer = ImageRenderer(content material: chartView)
if let picture = renderer.uiImage UIImageWriteToSavedPhotosAlbum(picture, nil, nil, nil)
label: Label(“Save to Photographs”, systemImage: “picture”)
.buttonStyle(.borderedProminent)
} |
Within the closure of the button, we create an occasion of ImageRenderer
with chartView
and get the rendered picture by utilizing the uiImage
property. Then we name UIImageWriteToSavedPhotosAlbum
to save lots of the picture to the picture album.
Observe: It’s worthwhile to add a key named Privateness – Photograph Library Utilization Description within the data.plist earlier than the app can correctly save a picture to the built-in picture album.
Including a Share Button

Earlier, you realized how to use ShareLink
to present a share sheet for content material sharing. With ImageRenderer
, you’ll be able to simply construct a operate for customers to share the chart view.
For comfort goal, let’s refactor the code for picture rendering right into a separate technique:
return renderer.uiImage ?? UIImage()
@MainActor personal func generateSnapshot() –> UIImage let renderer = ImageRenderer(content material: chartView)
return renderer.uiImage ?? UIImage()
|
The generateSnapshot
technique converts the chartView
into a picture.
Observe: In case you are new to @MainActor
, you’ll be able to check out this article.
With this helper technique, we will create a ShareLink
like this within the VStack
view:
ShareLink(merchandise: Picture(uiImage: generateSnapshot()), preview: SharePreview(“Climate Chart”, picture: Picture(uiImage: generateSnapshot()))) .buttonStyle(.borderedProminent) |
Now if you faucet the Share button, the app captures the road chart and allows you to share it as a picture.

Adjusting the Picture Scale
You could discover the decision of the rendered picture is a bit low. The ImageRenderer
class has a property named scale
so that you can alter the dimensions of the rendered picture. By default, its worth is about to 1.0. To generate a picture with a better decision, you’ll be able to set it to 2.0
or 3.0
. Alternatively, you’ll be able to set the worth to the dimensions of the display screen:
renderer.scale = UIScreen.important.scale |
Abstract
The ImageRenderer
class has made it very straightforward to transform any SwiftUI views into a picture. In case your app helps iOS 16 or up, you should use this new API to create some handy options on your customers. Apart from rendering pictures, ImageRenderer
additionally enables you to render a PDF doc. You’ll be able to check with the official documentation for additional particulars.
For charts, Apple additionally comes with a extra particular renderer referred to as ChartRendere
r for exporting a chart as a picture. Later, we’ll additional look into this class.