soleil
soleil

Reputation: 13135

Take a snapshot of view without adding it to the screen

I'm trying to load a view from a nib, configure it, and take a snapshot of it, without adding it to the screen:

+ (void)composeFromNibWithImage:(UIImage*)catImage completion:(CompletionBlock)completion {

    NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"CatNib" owner:nil options:nil];
    CatView *catView = [nibContents firstObject];

    //here, catView is the correct size from the nib, but is blank if inspected with the debugger

    catView.catImageView.image = catImage;
    catView.furButton.selected = YES;    
    UIImage *composite = [UIImage snapshot:catView];
    completion(composite);
}

where snapshot is the typical:

+ (UIImage *)snapshot:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

However, both catView and composite are sized correctly but blank as I step through the code. How can I create a UIImage from a view that is loaded from a nib, without adding the view to the screen?

Upvotes: 8

Views: 2949

Answers (3)

Abhishek Sharma
Abhishek Sharma

Reputation: 3283

    UIGraphicsBeginImageContext(view.frame.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

Upvotes: 0

croX
croX

Reputation: 1725

I had a similar issue some time ago, and as far as I can tell it is not possible to take a snapshot of a view, that is not actually on the screen. I created a workaround and placed the concerned view, which I wanted to snapshot, outside of the current ViewControllers view bounds, so that you won't see it. In this case it was possible to create a valid snapshot. Hope this helps :)

Upvotes: 3

timgcarlson
timgcarlson

Reputation: 3146

This feels a bit hacky, but I tried it and it does get the job done. If you load the view from your nib behind the main view, you can take a screenshot of just that layer. So long as it's not a memory intensive view, the user would never know that view was added to the super view.

UIGraphicsBeginImageContext(CGSizeMake(catView.frame.size.width, catView.frame.size.height));
CGContextRef context = UIGraphicsGetCurrentContext();
[catView.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

So run this code after you load your nib behind your main view. Once it's loaded you can remove it with `[catView removeFromSuperiew]'

Upvotes: 2

Related Questions