8

I found this code which is quite nice:

+ (UIImage *) imageWithView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

But I need to capture UINavigationBar as well because i want to use the image as transition layer in my UIStoryboardSegue. Any ideas?

cschuff
  • 5,502
  • 7
  • 36
  • 52

4 Answers4

7

Use your view's window as the view so the navigation bar and status bar will be included, too. If you need to remove the status bar, you'll have to crop the image.

Fabian Kreiser
  • 8,307
  • 1
  • 34
  • 60
  • How can i screenshot a viewcontroller including the navigationbar BEFORE pushing it? I need to screenshot the destination view controller fullscreen. – cschuff Jan 25 '12 at 21:40
  • If you have a pointer to the view controller, you can easily access that view controller's view even if it's not pushed yet. – Fabian Kreiser Jan 26 '12 at 13:24
  • Yes, but 1. does the navigation bar not belong to the view and 2. can't I access its NavigationBar before it's pushed. The navigation bars appearance in VC2 is different from VC1. – cschuff Jan 26 '12 at 17:25
  • You'll have to access the view's window, if you want to include the navigation bar or the navigation controller's view. If it's not pushed and you want to include the navigation bar, you'll have to push it before you take the screenshot. – Fabian Kreiser Jan 27 '12 at 05:36
4

You should take a screenshot of self.navigationController?.view . That way you get the whole view with navigationBar but without status bar.

if let view = self.navigationController?.view {
    let snapshot = view.snapshotViewAfterScreenUpdates(false)
}
Aleš Oskar Kocur
  • 1,381
  • 1
  • 13
  • 29
2

instead of view.layer give reference of appdelegate.window.layer it will work.

siddi
  • 56
  • 4
0

Wow, really none of these answers work. This is how you do it to get screenshot of everything including navigation controller

-(void) takeScreenshot
{

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
    {
        //its iphone


        CGSize result = [[UIScreen mainScreen] bounds].size;
        if(result.height == 480 || result.width == 480)
        {
            // iPhone Classic
            screenRect  = CGRectMake(0, 0, 320, 480);
        }
        if(result.height == 568 || result.width == 568)
        {
            // iPhone 5
            screenRect  = CGRectMake(0, 0, 320, 568);
        }
    }
    else
    {
        //its pad
        screenRect  = CGRectMake(0, 0, 768, 1024);
    }

    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];

    // This code is for high resolution screenshot
    UIGraphicsBeginImageContextWithOptions(screenRect.size, NO, 0.0);

    //this was pre iOS 7.0
    //[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    // iOS 7.x -->
    [[[[UIApplication sharedApplication] windows] objectAtIndex:0] drawViewHierarchyInRect:self.view.bounds afterScreenUpdates:YES]; // Set To YES

    UIImage *viewImage2 = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    NSData* imageData2 = UIImageJPEGRepresentation(viewImage2, 1.0);
    NSString* incrementedImgStr2 = [NSString stringWithFormat: @"UserScreenShotPic.jpg"];


    // Now we get the full path to the file
    NSString* fullPathToFile3 = [documentsDirectory stringByAppendingPathComponent:incrementedImgStr2];
    [imageData2 writeToFile:fullPathToFile3 atomically:NO];

}
Sam B
  • 27,273
  • 15
  • 84
  • 121