Getting a Screenshot of a Uiscrollview, Including Offscreen Parts

Getting a screenshot of a UIScrollView, including offscreen parts

Here is code that works ...

- (IBAction) renderScrollViewToImage
{
UIImage* image = nil;

UIGraphicsBeginImageContext(_scrollView.contentSize);
{
CGPoint savedContentOffset = _scrollView.contentOffset;
CGRect savedFrame = _scrollView.frame;

_scrollView.contentOffset = CGPointZero;
_scrollView.frame = CGRectMake(0, 0, _scrollView.contentSize.width, _scrollView.contentSize.height);

[_scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();

_scrollView.contentOffset = savedContentOffset;
_scrollView.frame = savedFrame;
}
UIGraphicsEndImageContext();

if (image != nil) {
[UIImagePNGRepresentation(image) writeToFile: @"/tmp/test.png" atomically: YES];
system("open /tmp/test.png");
}
}

The last few lines simply write the image to /tmp/test.png and then opens it in Preview.app. This obviously only works on in the Simulator :-)

Complete project in the ScrollViewScreenShot Github Repository

Getting a full screenshot of a UIScrollView in iOS 13

It's seems like iOS 13 bug but I found the solution in this answer.

The solution is I am removing scrollview from superview and then adding in with its old constraints after taking the screenshot. Yeah, it's stupid but it just works that way :(

scrollView.removeFromSuperview()
let print = scrollView.screenshot()
mainView.addSubview(scrollView)
scrollView.snp.makeConstraints { (make) in
make.top.equalTo(topView.snp.bottom)
make.left.bottom.right.equalToSuperview()
}

How to make a screenshot of all the content of a Scrollview?

To Swift from this answer, adding a test ViewController:

class ScreenShotTestViewController: UIViewController {

var scrollView: UIScrollView!

override func viewDidLoad() {
super.viewDidLoad()
scrollView = UIScrollView(frame: CGRect(origin: CGPoint.zero, size: view.frame.size))
scrollView.contentSize = CGSize(width: view.frame.size.width, height: view.frame.size.height * 2)
scrollView.backgroundColor = UIColor.yellow
view.addSubview(scrollView)

let label = UILabel(frame: CGRect(x: 0.0, y: view.frame.size.height * 1.5, width: view.frame.size.width, height: 44.0))
label.text = "Hello World!"
scrollView.addSubview(label)

let screenShot = snapshot()
}

func snapshot() -> UIImage?
{
UIGraphicsBeginImageContext(scrollView.contentSize)

let savedContentOffset = scrollView.contentOffset
let savedFrame = scrollView.frame

scrollView.contentOffset = CGPoint.zero
scrollView.frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height)

scrollView.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()

scrollView.contentOffset = savedContentOffset
scrollView.frame = savedFrame

UIGraphicsEndImageContext()

return image
}
}

Results in an image of the complete content, including subviews:

Sample Image

Take screenshot of ViewController with scrollview

What you are doing is taking the screenshot of SuperView which is on top of UIViewController. You need to take screenshot of UIScrollView and for that you need to pass the contentSize of UIScrollView.

//Create the UIImage

UIGraphicsBeginImageContext(scrollView.contentSize) //Change this line only
view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
sharedImage = image

Now you will get the screenshot of complete UIScrollView.

How to take an iPhone screenshot of entire view including parts off screen?

Just pasting some code I used in my app. It draws a view to an image (potentially scaling).
Maybe you could programmaticaly scroll the table and stitch the images together in the end or something similar:

+ (UIImage *)captureView: (UIView *)view inSize: (CGSize)size
{
UIGraphicsBeginImageContext(size);
CGSize viewSize = view.frame.size;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM( context, size.width/viewSize.width, size.height/viewSize.height);

[view.layer renderInContext: UIGraphicsGetCurrentContext()];

UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}

Hope it helps



Related Topics



Leave a reply



Submit