Reputation: 211
I want to capture a view with its subviews. I'm using this code to capture the screen:
let view = self.faceTrackerContainerView
UIGraphicsBeginImageContext(CGSizeMake(view.bounds.size.width, view.bounds.size.height))
UIGraphicsGetCurrentContext()!
self.view?.drawViewHierarchyInRect(view.frame, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
These codes capture the whole screen including a button that's in front of the view. I tried these codes but it only captures the main view excluding its subviews:
let view = self.faceTrackerContainerView
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, scale);
view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
I also tried the snapshotViewAfterScreenUpdates(true)
from here but I don't know how to implement it. I have a collectionView below the view and a button on top of the view (both are not in the view). The first codes capture everything with the button, collectionView, and subviews. The second codes capture the view without the subviews. What am I missing?
Upvotes: 14
Views: 16743
Reputation: 943
Add all subviews(that you want to include in screenshot) to one parent view.
Draw parent view hierarchy like this:
let renderer = UIGraphicsImageRenderer(size: mapParentView.bounds.size) let image = renderer.image { ctx in mapParentView.drawHierarchy(in: mapParentView.bounds, afterScreenUpdates: true) }
Upvotes: 0
Reputation: 6413
extension UIView {
func asImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
layer.render(in: rendererContext.cgContext)
}
}
}
It makes an UIImage from a UIView. Then you can use that image with UIImageView(image:) method
Upvotes: 10
Reputation: 583
It isn't very elegant, but hiding views before the screenshot is taken works. You can then make them visible afterwards.
view.isHidden = true
//screenshot
view.isHidden = false
Upvotes: 1
Reputation: 16820
This is working for me,
func screenShotMethod() {
//Create the UIImage
UIGraphicsBeginImageContext(faceTrackerContainerView.frame.size)
faceTrackerContainerView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//Save it to the camera roll
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
Upvotes: 17