ImageRenderer fails to render Picker

When using the new ImageRenderer introduced in iOS16, the Picker control does not render correctly. I have filed it as FB11994261.

Does anyone have a workaround for this which still uses ImageRenderer?

As an aside: the reason I need to use ImageRenderer is that in my current project I'm trying to render a large (>2730 point tall) view to an image for the user to share. Solutions using UIGraphicsImageRenderer will silently fail with a clear/black screen when trying to render views with any dimension >2730 pt. ImageRenderer is the only view capturing technique that I've found which will successfully render a View greater than this threshold.

To replicate:

add a Picker to a view. Attempt to render that view using ImageRenderer. The resulting image will not match what is displayed on screen.

Step-by-step: Create a default SwiftUI project in Xcode. Replace the main content view with this code:

struct ContentView: View {
    @State private var renderedImage: UIImage?
    @State private var showSheet = false
    @State private var picked: Int = 0
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Picked \(picked)")
            Picker("Pick a number", selection: $picked) {
                ForEach([0,1,2,3], id:\.self) { number in
                    Text("\(number)")
                }
            }
            .pickerStyle(.segmented)
        }
        .padding()
        .sheet(isPresented: $showSheet) {
            if let renderedImage {
                Image(uiImage: renderedImage)
            }
        }
        .task {
            Task {
                renderedImage = ImageRenderer(content: self).uiImage!
                showSheet = true
            }
        }
    }
}

Expected result:

on loading the view, ImageRenderer captures the current state of ContentView, a sheet opens, and the screenshot is display, including the Picker UI element.

Actual results:

The screenshot is presented in a sheet, but the Picker element is replaced by a yellow field with a red slash-circle in the center. Attached are images of the actual ContentView, and the sheet displaying the failed render.

Answered by igeek123 in 755571022

I just figured this out: in some contexts, some views will not be rendered if they're backed by AppKit or UIKit. Widgets, ImageRender, and the new shader APIs will refuse to play with those types of views. See the callout right above this section in the docs. Buttons, for instance, will work but ProgressViews or Pickers will not.

Accepted Answer

I just figured this out: in some contexts, some views will not be rendered if they're backed by AppKit or UIKit. Widgets, ImageRender, and the new shader APIs will refuse to play with those types of views. See the callout right above this section in the docs. Buttons, for instance, will work but ProgressViews or Pickers will not.

ImageRenderer fails to render Picker
 
 
Q