Here below is my sample demo view and a swift button to trigger it.
The wired thing is: when the screenshot image is very long (like, we have more than 40 items below), it only saves an empty image. However, it can store an valid image with all the content, when there are fewer items (like, it is fine if there are only 20 items).
note: the xcode project target is "ios 15.0". Anything wrong with my code? please help.
//
// ContentView.swift
// TestSample1
import SwiftUI
struct ContentView: View {
func getContentView() -> some View {
ScrollView {
ForEach(1...42, id:\.self) { event in
Text("event \(event)")
.frame(width: 400, height: 60, alignment: .center)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.padding(EdgeInsets(top: 0, leading: 0, bottom: 40, trailing: 0))
}
var body: some View {
GeometryReader { geometry in
VStack {
getContentView()
Button(action: {
let dataView = getContentView()
let image = dataView.snapshot(size: geometry.size)
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}) {
HStack(alignment: .center, spacing: 0) {
Image(systemName: "photo")
Text("homepage_action_save")
}
}.font(.system(.title3, design: .rounded))
}
}
}
}
extension View {
func snapshot(size: CGSize) -> UIImage {
let controller = UIHostingController(rootView: self)
let view = controller.view
var targetSize = controller.view.intrinsicContentSize
targetSize.width = size.width
view?.bounds = CGRect(origin: .zero, size: targetSize)
view?.backgroundColor = .clear
let renderer = UIGraphicsImageRenderer(size: targetSize)
return renderer.image { _ in
print(controller.view.bounds)
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}