Member-only story
SwiftUI: How to take screenshot of ScrollView Content?
Xcode 12 — iOS 14
In this tutorial, We will be converting ScrollView’s content into a UIImage.
First, we will convert any view into the UIImage then we will extend the same logic to screenshot the entire Scroll view content.
- Create an extension on SwiftUI’s view, which takes the position of part of the view we need to convert into an image. We will create a dummy UIHostingViewController with the given frame. From UIHostingView controller, we will access UIKit’s view.
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.frame = window.frame
window.addSubview(hosting.view)
window.makeKeyAndVisible()
return hosting.view.screenShot
}
}
2. Getting Image from UIKit’s UIView: For this, we are going to use simple core graphics apis like following:
extension UIView {
var screenShot: UIImage {
let rect = self.bounds
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
let context: CGContext = UIGraphicsGetCurrentContext()!
self.layer.render(in: context)
let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return capturedImage
}
}
3. Triggering Image from SwiftUI View: As we need to pass frame, We need to wrap view in Geometry Reader.
GeometryReader { proxy in
VStack {
Button(action: {
let image = self.takeScreenshot(origin: proxy.frame(in: .global).origin, size: proxy.size)
print(image) //save your image here
}) {
RoundedRectangle(cornerRadius: 20)
.fill(self.color)
.overlay(
VStack {
Text("size: \(proxy.size.debugDescription)")
.foregroundColor(.white)
})
}
}
}.frame(height: 100)
4. Reading ScrollView’s content frame: We will add Geometry Reader on ScrollView’s content background and repeat step 3 to take the screenshot.
We will be building ScrollView’s content in a separate view container, As we want to create UIHostingView on Content view and not on its parent.