How to take a screenshot of List in a ScrollView of SwiftUI?

I found this way to take screenshot in full screen view of SwiftUI. But How to take screenshot of a ScrollView content view?

Thanks!




Normal way:

SwiftUI Extension

Code Block swift
extension View {
  func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage {
    let window = UIWindow(frame: CGRect(origin: origin, size: size))
    let hosting = UIHostingController(rootView: self)
    window.rootViewController = hosting
    window.makeKeyAndVisible()
    return hosting.view.snapshotImage()!
  }
}


Swift Extension
Code Block swift
extension UIView {
func snapshotImage() -> UIImage {
.....
}
}

Answered by Abenx in 620662022
Lucky, I found a way to take screenshot in scrollview


Code Block swift
...
struct ColorGroupView: View {
  var colors: [UIColor]
  @State var coverImage: UIImage
  var body: some View {
    let content =
      VStack {
        ForEach(1...50, id: \.self) { i in
          Text("Hello \(i)")
            .frame(maxWidth: .infinity, minHeight: 60)
        }
    }
     
    return GeometryReader { geometry in
      VStack(spacing: 0) {
        ScrollView {
          content
        }
        ScrollView {
          Image(uiImage: self.coverImage)
            .frame(maxWidth: .infinity, minHeight: 60)
        }
        HStack{
          Button("Button") {
            let screenshot = content.takeScreenshot(origin: geometry.frame(in: .global).origin, size: geometry.size)
            self.coverImage = screenshot
          }
        }
        .padding()
        .padding(.bottom, geometry.safeAreaInsets.bottom)
        .frame(maxWidth: .infinity)
        .background(VisualEffectBlur())
      }
      .edgesIgnoringSafeArea(.bottom)
    }
  }
}
extension View {
  func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage {
    let window = UIWindow(frame: CGRect(origin: origin, size: size))
    let hosting = UIHostingController(rootView: self)
     
    hosting.view.sizeToFit()
     
    window.height = hosting.view.frame.size.height > 0 ? hosting.view.frame.size.height : window.height
    window.width = hosting.view.frame.size.height > 0 ? hosting.view.frame.size.height : window.width
     
    window.rootViewController = hosting
    window.makeKeyAndVisible()
    return window.snapshotImage()!
  }
}
...
extension UIView {
func height ...
func width ...
func snapshotImage ...

Accepted Answer
Lucky, I found a way to take screenshot in scrollview


Code Block swift
...
struct ColorGroupView: View {
  var colors: [UIColor]
  @State var coverImage: UIImage
  var body: some View {
    let content =
      VStack {
        ForEach(1...50, id: \.self) { i in
          Text("Hello \(i)")
            .frame(maxWidth: .infinity, minHeight: 60)
        }
    }
     
    return GeometryReader { geometry in
      VStack(spacing: 0) {
        ScrollView {
          content
        }
        ScrollView {
          Image(uiImage: self.coverImage)
            .frame(maxWidth: .infinity, minHeight: 60)
        }
        HStack{
          Button("Button") {
            let screenshot = content.takeScreenshot(origin: geometry.frame(in: .global).origin, size: geometry.size)
            self.coverImage = screenshot
          }
        }
        .padding()
        .padding(.bottom, geometry.safeAreaInsets.bottom)
        .frame(maxWidth: .infinity)
        .background(VisualEffectBlur())
      }
      .edgesIgnoringSafeArea(.bottom)
    }
  }
}
extension View {
  func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage {
    let window = UIWindow(frame: CGRect(origin: origin, size: size))
    let hosting = UIHostingController(rootView: self)
     
    hosting.view.sizeToFit()
     
    window.height = hosting.view.frame.size.height > 0 ? hosting.view.frame.size.height : window.height
    window.width = hosting.view.frame.size.height > 0 ? hosting.view.frame.size.height : window.width
     
    window.rootViewController = hosting
    window.makeKeyAndVisible()
    return window.snapshotImage()!
  }
}
...
extension UIView {
func height ...
func width ...
func snapshotImage ...

https://github.com/rushairer/ScreenshotableView

My made a 'ScreenshotableView' to fix this issue
Thanks, I found something similar from last year from Sato Takeshi that looked very similar.
Code Block

How to take a screenshot of List in a ScrollView of SwiftUI?
 
 
Q