My application allow user to switch UIImageView back and front and then user can capture that screen. Here is my code to capture the screen into UIImage
-(UIImage *)imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 2.0f);
// I even tried view.layer.presentationLayer but still not working
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
I do not use [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES] because it is slower and sometimes (when view is not visible) drawn the screenshot in black.
But problem with renderInContext is the Z position that change between UIImageView ( imageView.layer.zPosition = 0.01;etc ). In my iPhone screen this work correctly when I assigned value to zPosition but in the capture screen it turns out wrong.
Are there anyway I can resolve this problem ? Thanks in advance
Edited: Here is what I tried to do before capture the screenshot. I use this code to make one ImageView display in front of another one.
-(void)bringOneLevelUp:(UIImageView*)imageView
{
//_imgArray is sorted by Z position order (small to big)
NSUInteger currentObjectIndex = [_imgArray indexOfObject:imageView];
if(currentObjectIndex+1< _imgArray.count){
UIImageView *upperImageView = [_imgArray objectAtIndex:currentObjectIndex+1];
CGFloat currentZIndex = imageView.layer.zPosition;
CGFloat upperZIndex= upperImageView.layer.zPosition;
imageView.layer.zPosition = upperZIndex;
upperImageView.layer.zPosition = currentZIndex;
// swap position in array
[_imgArray exchangeObjectAtIndex:currentObjectIndex withObjectAtIndex:currentObjectIndex+1];
}
}
And liked I explained earlier the result of this code in the phone screen is correct. The newImageView is in front of lastImageView. But when I captured screenshot by renderInContext. They are not.
Swift 4.2
The answer of @RameshVel worked for me translating it to Swift, maybe someone needs this:
UIGraphicsBeginImageContext(drawingCanvas.frame.size)
self.renderInContext(ct: UIGraphicsGetCurrentContext()!)
guard let image = UIGraphicsGetImageFromCurrentImageContext() else {return}
UIGraphicsEndImageContext()
And in the renderInContext function:
func renderInContext(ct:CGContext){
ct.beginTransparencyLayer(auxiliaryInfo: nil)
// descendant ordered list of views based on its z-position
let orderedLayers = self.view.subviews.sorted(by: {
$0.layer.zPosition < $1.layer.zPosition
})
for l in orderedLayers {
l.layer.render(in: ct)
}
ct.endTransparencyLayer()
}
The same can be donde with CALayers if you are drawing and adding layers:
UIGraphicsBeginImageContext(drawingCanvas.frame.size)
//Canvas is a custom UIView for drawing
self.renderInContext(ct: UIGraphicsGetCurrentContext()!, canvas: canvas)
guard let image = UIGraphicsGetImageFromCurrentImageContext() else {return}
UIGraphicsEndImageContext()
renderInContext function:
func renderInContext(ct:CGContext, canvas:CustomCanvas){
ct.beginTransparencyLayer(auxiliaryInfo: nil)
let layers:[CALayer] = canvas.layer.sublayers!
let orderedLayers = layers.sorted(by: {
$0.zPosition < $1.zPosition
})
for v in orderedLayers {
v.render(in: ct)
}
ct.endTransparencyLayer()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With