Take a snapshot of view without adding it to the screen
Asked Answered
P

3

8

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?

Porch answered 13/2, 2015 at 21:58 Comment(0)
T
2

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]'

Taima answered 16/2, 2015 at 23:40 Comment(1)
I was aware that I could do this by somehow adding the view to an invisible portion of the screen. I'm actually calling this code from an NSObject subclass which doesn't have a reference to the main view so I was hoping there was a way to just load the nib, customize it, and snapshot it, but I guess not.Porch
F
3

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 :)

Fadeout answered 16/2, 2015 at 23:46 Comment(0)
T
2

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]'

Taima answered 16/2, 2015 at 23:40 Comment(1)
I was aware that I could do this by somehow adding the view to an invisible portion of the screen. I'm actually calling this code from an NSObject subclass which doesn't have a reference to the main view so I was hoping there was a way to just load the nib, customize it, and snapshot it, but I guess not.Porch
F
0
    UIGraphicsBeginImageContext(view.frame.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
Fenner answered 23/2, 2015 at 12:49 Comment(1)
I think it would be more helpful for the OP and further visitors, whenn you add some explaination to your intension.Schottische

© 2022 - 2024 — McMap. All rights reserved.