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.

  1. 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.

--

--

Prafulla Singh
Prafulla Singh

Responses (2)