5

I have a problem that I can't seem to fix. I am trying to take a screen-shot of a UIScrollView (including off-screen content) but when the view is long the renderInContext doesn't get all the contents of the scroll view. The produced image dimensions are correct but the rendered data appears to be missing chunks of the display leaving white space where those chunks should be. The missing blocks are from the content in a UIWebView, which I believe is set to "scaleToFit". It doesn't happen everytime, it appears to only happen when the UIWebView's height if fairly large. Which makes me think is has to do with the scaling of the UIWebView.

If I adjust the coreLayer.bounds CGRECT below I get different results, sometimes the missing blocks are at the bottom and sometimes they are in the middle of the image.

I started with the code from the accepted answer of this question and when I noticed the cutoff issue, I modified it to the following:

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


    //hide the scroll bars
    [scrollView setShowsHorizontalScrollIndicator:NO];
    [scrollView setShowsVerticalScrollIndicator:NO];


    scrollView.contentOffset = CGPointZero;
    scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
    //adjust layer for cut-off
    CALayer *coreLayer = scrollView.layer;
    coreLayer.bounds = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
    [coreLayer renderInContext: UIGraphicsGetCurrentContext()]; 
    //[scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
    image = UIGraphicsGetImageFromCurrentImageContext();

    scrollView.contentOffset = savedContentOffset;
    scrollView.frame = savedFrame;


    //reset the scroll bars to default
    [scrollView setShowsHorizontalScrollIndicator:YES];
    [scrollView setShowsVerticalScrollIndicator:YES];
}
UIGraphicsEndImageContext();

The cut-off adjustment helped (fixed it with some views) but its still getting cut-off when the UIScrollView is fairly long. I've been working on this for a while and can't seem to find a fix. Do you have any suggestions? Has anyone ever encountered this issue?

Please help!

Community
  • 1
  • 1
thiesdiggity
  • 1,897
  • 2
  • 18
  • 27
  • Just a thought but have you considered temporarily changing scrollView.frame.size to scrollView.contentSize? This will require the table view to load all cells in, as they're fitting into the frame (table views cache content outside of their frame, not outside of the screen). – Kalle Oct 02 '12 at 22:49

1 Answers1

0

Is your scroll view a table view? If so, pretty much only the onscreen content actually exists due to cell reuse. Even if it's a regular scroll view, it's plausible that the OS is making optimizations by not rendering some offscreen elements of the scroll view. If that's true, you may be able to get this to work by programmatically scrolling one screenful at a time and rendering each of those into your context at the right position.

Zev Eisenberg
  • 8,080
  • 5
  • 38
  • 82
  • Yup, that is exactly what it is doing and I had to figure out how much is actually rendered. What I found was that there is usually 3 "blocks" that are viewable at a time. Then as you scroll the UIScrollView those re-draw content based on the direction of the scroll. So I am taking a screenshot of the 3 panel area, scrolling it to the next viewable 3 panels, etc, etc. – thiesdiggity Sep 25 '12 at 22:29
  • I would caution you to make sure your code doesn’t have the number 3 hard-coded. The number of rows that are drawn offscreen may be an implementation detail that could change with a new OS release or even be different on another device, depending on available RAM or GPU capabilities. – Zev Eisenberg Sep 26 '12 at 21:06