ImageRenderer fails to render contents of ScrollViews

Is everyone else seeing that ImageRenderer is unable to render the contents of a ScrollView? When using the ImageRenderer class introduced in iOS16, the render will not contain any Views that are inside of a ScrollView. The ScrollView contents within the rendered image will be blank. This is surprising to me since I would think ScrollView use is pretty common, and so ImageRenderer would have been tested with it. Is there any documentation out there explaining what types of Views or scenarios will cause a failure of ImageRenderer?

To reproduce, run the ContentView below inside an iOS SwiftUI project. Tap the “Render this View to Image” button. Expected results: the green-bordered Image should show a screenshot of the entire View, including the contents of the ScrollView (“Text inside a ScrollView”). Actual results: the rendered screenshot shows the region of the ScrollView, but there are no contents shown. It is blank.

import SwiftUI



struct ContentView: View {
    @State private var renderedImage: UIImage?
    var body: some View {
        VStack {
            Button("Render this View to Image") {
                renderedImage = ImageRenderer(content: self).uiImage!
            }
            VStack {
                Text("rendered image")
                Image(uiImage: renderedImage ?? UIImage(systemName: "xmark")!)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
            }
            .frame(height: 200, alignment: .center)
            .padding(5).border(.green, width: 5)
            VStack {
                Text("A ScrollView is shown below")
                ScrollView {
                    VStack {
                        Text("Text inside a ScrollView")
                        Text("Text inside a ScrollView")
                        Text("Text inside a ScrollView")
                        Text("Text inside a ScrollView")
                    }
                    .fixedSize()
                }
            }
            .padding(5).border(.red, width: 5)
            .frame(height: 100)
        }
        .padding()
    }
}

Answered by rkhamilton in 757831022

I wanted to close this out. I got a response to my Feedback indicating that this is the expected behavior.

ImageRenderer output only includes views that SwiftUI renders, such as text, images, shapes, and composite views of these types. It does not render views provided by native platform frameworks (AppKit and UIKit) such as web views, media players, and some controls. For these views, ImageRenderer displays a placeholder image, similar to the behavior of drawingGroup(opaque:colorMode:).

I wish there was a way for me to know which views are provided by native frameworks so I could predict if ImageRenderer would fail, but there you go.

Update: this was submitted as FB11995723

I can confirm that this was also the case in my project.

Same here, but also ANY refactored view.

Accepted Answer

I wanted to close this out. I got a response to my Feedback indicating that this is the expected behavior.

ImageRenderer output only includes views that SwiftUI renders, such as text, images, shapes, and composite views of these types. It does not render views provided by native platform frameworks (AppKit and UIKit) such as web views, media players, and some controls. For these views, ImageRenderer displays a placeholder image, similar to the behavior of drawingGroup(opaque:colorMode:).

I wish there was a way for me to know which views are provided by native frameworks so I could predict if ImageRenderer would fail, but there you go.

ImageRenderer fails to render contents of ScrollViews
 
 
Q