I have a UIScrollView
decendent that implements a takeScreenshot method that looks like this:
-(void)takeScreenshot {
CGRect contextRect = CGRectMake(0, 0, 768, 1004);
UIGraphicsBeginImageContext(contextRect.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// do something with the viewImage here.
}
This basically moves to the top of the scroll view, and takes a screenshot of the visible area. It works fine when the iPad is oriented portrait, but when it's in landscape the bottom of the image is cut off (as the height of the visible area is only 748, not 1004).
Is it possible to get a snapshot of the UIScrollView
, including areas not on screen? Or do I need to scroll the view down, take a second photo and stitch them together?
SWIFT 3 version:
This worked for me
SWIFT 3 version thanks to @gleb vodovozov:
I took the solution above from @Roopesh Mittal and made it safer/cleaner.
Swift 4 compatible
Here's another way of doing it, which takes the zoom level into account. I have a scrollview with 4 different UIImageView layers in it, and I want to take a screenshot of their current state:
This takes the screenshot in absolute coordinates. That is, if you have a 2048*2048 image in the scrollview and you can see about a quarter of it, then regardless of the resolution of your screen it would take a screenshot of 512*512. If you want to take a screenshot at your screen resolution (say, 320*480) then you have to adjust the image as follows, directly after the above code:
for me answer https://stackoverflow.com/a/3539944/4164443 didn't work. I had a task of implementing this on iOS 8.
Actually this method works for iPhone, but iPad (both simu and real device) is another case. It just renders visible part and the rest of image is just blank.
I tried with
drawViewHierarchyInRect
- no luck. Depending onafterScreenUpdates
beingtrue
orfalse
I got stretched part of image or again only part of image.So the only way I found to achieve correct screenshoting is to add scrollview to another temp view and render it.
Sample code is below (scrollview is outlet in my VC)
A refined Swift 4.1 version, based on @RyanG 's answer: