Snapshotting a SwiftUI View isn’t as convenient as for UIKit UIView, but it worked well for iOS 13 & 14. I encountered the padding issue while working on Reverse Meme Search
during iOS 15 release, the exported images suddenly had some weird padding.
If you just want the code, check this GitHub Gist
.
1. The initial code
Let’s first review the code that was working well before iOS 15.
You can find some alternatives, but the overall idea is there. We wrap the SwiftUI View within an UIHostingController, and we render it using UIGraphicsImageRenderer.
2. The fix
I couldn’t find the root cause leading to the bug, but I assume it’s a change within how safe area is managed in iOS 15.
Leading us to modify the code with this:
1
2
3
4
5
// Note: since iOS 15 it seems these two modifiers are required.letcontroller=UIHostingController(rootView:self.ignoresSafeArea().fixedSize(horizontal:true,vertical:true))
Applying these two modifiers seems to do the trick to avoid the weird padding:
extensionView{funcsnapshot()->UIImage?{// Note: since iOS 15 it seems these two modifiers are required.letcontroller=UIHostingController(rootView:self.ignoresSafeArea().fixedSize(horizontal:true,vertical:true))guardletview=controller.viewelse{returnnil}lettargetSize=view.intrinsicContentSizeiftargetSize.width<=0||targetSize.height<=0{returnnil}view.bounds=CGRect(origin:.zero,size:targetSize)view.backgroundColor=.clearletrenderer=UIGraphicsImageRenderer(size:targetSize)returnrenderer.image{_inview.drawHierarchy(in:controller.view.bounds,afterScreenUpdates:true)}}}