I use the following bit of code to snapshot a View as a UIImage, but it's causing a memory leak:
extension View {
@ViewBuilder func snapshot(trigger: Bool, onComplete: @escaping (UIImage) -> ()) -> some View {
self.modifier(SnapshotModifier(trigger: trigger, onComplete: onComplete))
}
}
fileprivate struct SnapshotModifier: ViewModifier {
var trigger: Bool
var onComplete: (UIImage) -> ()
@State private var view: UIView = .init(frame: .zero)
func body(content: Content) -> some View {
content
.background(ViewExtractor(view: view))
.compositingGroup()
.onChange(of: trigger) {
generateSnapshot()
}
}
private func generateSnapshot() {
if let superView = view.superview?.superview {
let render = UIGraphicsImageRenderer(size: superView.bounds.size)
let image = render.image { _ in
superView.drawHierarchy(in: superView.bounds, afterScreenUpdates: true)
}
onComplete(image)
}
}
}
fileprivate struct ViewExtractor: UIViewRepresentable {
var view: UIView
func makeUIView(context: Context) -> UIView {
view.backgroundColor = .clear
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
// No process
}
}
Taking the snapshot is triggered like this:
struct ContentView: View {
@State private var triggerSnapshot: Bool = false
var body: some View {
Button("Press to snapshot") {
triggerSnapshot = true
}
TheViewIWantToSnapshot()
.snapshot(trigger: triggerSnapshot) { image in
// Save the image; you don't have to do anything here to get the leak.
}
}
}
I'm not the best at Instruments, and this is what the Leaks template produces. There are no method names, just memory addresses:
Is this leak in an internal iOS library, is there something wrong with Instruments, or am I missing something obvious in my code?
Thanks.
Our engineering teams need to investigate this issue, as resolution may involve changes to Apple's software. Please file a bug report, include a small Xcode project and some directions that can be used to reproduce the problem, and post the Feedback number here once you do. If you post the Feedback number here I'll check the status next time I do a sweep of forums posts where I've suggested bug reports.
Bug Reporting: How and Why? has tips on creating your bug report.