I think UIScreen.main.snapshotView(afterScreenUpdates: true) work does not the way you expect behavior.
It seems that this function create transparent visual filter and display all views in frozen state behind him, like stamp
You need add snapview like subview to main view, execute needed operation and then remove added view from superview
view.addSubview(snapview)
...do something...
snapview.removeFromSuperview()
And of course you have to handle the flash effect when adding and removing
view.layer.opacity = 0
UIView.animate(withDuration: 0.25) {
view.layer.opacity = 1
}
Tested on iPhone6s (iOS 14.6 Xcode 12.5.1)
ScreenCapturer.swift
static func capture(view: UIView) {
let snapview = UIScreen.main.snapshotView(afterScreenUpdates: true)
let renderer = UIGraphicsImageRenderer(size: snapview.bounds.size)
let image = renderer.image { _ in
view.addSubview(snapview)
view.drawHierarchy(in: snapview.bounds, afterScreenUpdates: true)
snapview.removeFromSuperview()
}
if let data = image.jpegData(compressionQuality: 0.8) {
do {
let url = try captureFileUrlNow()
try data.write(to: url)
print(url) // so we can check manually what got written in simulator
} catch {
print("ERROR:", error)
}
}
}
Function call from ViewController.swift
ScreenCapturer.capture(view: self.view)
To test the behavior of UIView.snapshotView() you can delete UIScreen.main.snapshotView (afterScreenUpdates: true) altogether and create a new UIView with the appropriate screen size, and this will be correct
static func capture(view: UIView) {
var snapview = UIView(frame: view.frame)
snapview = view.snapshotView(afterScreenUpdates: false)!
let renderer = UIGraphicsImageRenderer(size: snapview.bounds.size)
let image = renderer.image { _ in
view.addSubview(snapview)
view.drawHierarchy(in: snapview.bounds, afterScreenUpdates: true)
snapview.removeFromSuperview()
}
if let data = image.jpegData(compressionQuality: 0.8) {
do {
let url = try captureFileUrlNow()
try data.write(to: url)
print(url) // so we can check manually what got written in simulator
} catch {
print("ERROR:", error)
}
}
}
In general, UIView.snapshotView() is convenient to use to create a menu with the main view sliding to the side (or anywhere else), so you will be sure that when the main view returns, you will not interact with the elements and accidentally cause unwanted behavior with the view elements (clicking buttons, gesture recognition, or something else)
Note:
This method is not suitable for creating a screenshot of the screen if there is an element with a live video from the camera, there will be an empty area, in this case it is necessary to take a photo from the camera and overlay a snapshot of the elements