views:

362

answers:

3

I have an application that's laid out using an UITableView. The interface takes up more than just the screen, so there's some area that can be scrolled to. I would like some screenshots of the entire view (including the non-visible area) to use for documentation and soliciting feedback from my customer.

Is there programmatic way to get an image of the entire view? I don't think there would be a way on the device to do this, but maybe there is.

+1  A: 

With a table view on the iphone, there is no "extra" area to scroll to. The table view is as big as the screen, and as new cells are scrolled into view, they're created on demand, while old cells that are scrolled off screen are deallocated.

Jasarien
Duly noted, however that doesn't really solve my problem of getting a screenshot of the entire interface (without multiple shots and then splicing them together).
Bearddo
He's saying you do get the a screenshot of the entire interface. The parts of the table off screen are just logical. They have no visual manifestation at all. A table is not like a scrollview which just shows you part of a larger view. With a table, what you see is what exist. Every time you scroll the table, it rebuilds itself. Until you scroll to a position off screen, that position does not exist visually.
TechZen
@TechZen Yes, I understand that it builds it on the fly, what I want is a screenshot of the entire interface as if all logical cells were drawn (with as much space as that takes).
Bearddo
@Bearddo so, to clarify, what you want is a picture of a really stretched out iPhone?
cobbal
Effectively, yes. Like say you wanted a picture of all your contacts in the Contacts app, not just the visible. Since I have the source to my app, I should be able to do this. Maybe just build a UITableView and lie to it about the size, and then render it with a different graphics context?
Bearddo
@Bearddo Yep, you can add together the height of all the rows (using the UITableViewDelegate methods that you have already defined) and set that as the size for the table view itself. Then the problem turns into the more generic, and pretty interesting, one of capturing the whole interface, including views that are off-screen.
Felixyz
@Bearddo - I think you're banging you head against the wall trying to programmatically capture something that the user will never, ever see. I do not believe the non-visible rows will ever be drawn into the context. I believe the table will always truncate its drawing at the screen edge. It might be an interesting drill type problem but I wouldn't waste any production time on it.
TechZen
Although, it occurs to me that if you had a certain undisclosed SDK that ran on a wink, wink, nudge, nudge larger screen that was nevertheless very much like the iPhone, then you could configure a table to draw larger than the iPhone screen and capture that.
TechZen
@TechZen You aren't limited to the size of the screen, I just made the UITableView large enough to show everything, and write it do a different context (the same size) as shown in the accepted answer. Despite the user never seeing it that way, my client wants to see the entire user interface in one image, not separate ones and this will save me tons of time by not having to slice and dice separate images.
Bearddo
Hah! Well, that's good know, it might prove useful in the future. It's not so bad being wrong when you learn something neat.
TechZen
+1  A: 

As Jasarien said, a UITableView has no off screen elements. It's just a stage illusion that creates the appearance of single long element.

If you want to create an image of long (i.e. offscreen) table, you should take screenshots of the table at different scroll positions and then Photoshop/GIMP/insert-graphics-app the screenshots into one long graphic.

TechZen
+1  A: 

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

Plamen Dragozov
Yup, works like a champ if instead of making it scale, you simply use the size of the view, and when creating the UITableView, you make it tall enough for all logical cells in the view and standard width.
Bearddo