This is part of an ELC Tech Network

Programmatically Getting a Screencapture of any UIView

Introduction

Hey guys. This post is in response to a comment made in my last post about NSTimers. Techy asked if we could do a post on how to take screenshots programmatically using the iPhone SDK. For this minor project we will be creating a small web browser application that will start at www.google.com, and have a button on a toolbar at the bottom to take a picture of the web view and save it into you photo library. Lets take a look.

Screenshots

Source

You can get the source here: Screenshot Project

Steps

Step 1

Create a view based application in xCode. Call it whatever.

Step 2

In the header for your view controller declare the following:

9438743f253c50279e305eb0d96b2363000

Step 3

Open up your view controller’s XIB file.

Advertisement

  • Drag in a UIToolbar and put it at the bottom of the screen.
  • Drag in a UIToolbarButtom and name it appropriately.
  • Drag in a flexible space holder on either side of the button to center it.
  • Drag in a UIWebView to take up the rest of the screen above the toolbar.
  • Connect the UIWebView to our webview IBOutlet.
  • Connect out UIToolbarButton to our IBAction catureScreen:(id)sender.

Step 4

Uncomment out the viewDidLoad method and use the following code:

- (void)viewDidLoad
{
    [super viewDidLoad];
 
    [webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]]];
}

Step 5

All the is left to do is create the IBAction captureScreen. This is the code for the method, place it in the main file for your view controller.

-(IBAction)captureScreen:(id)sender
{
	UIGraphicsBeginImageContext(webview.frame.size);
	[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}

Conclusion

So that is it. You can use this general code to take a screenshot of any UIView subclass. All you need to do is replace webview.frame.size in the third line with foobar.frame.size where foobar is any UIView subclass. Hope this answered your question Techy. Happy Coding.

This entry was posted in Uncategorized. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

10 Comments

  1. Marcelo
    Posted July 27, 2009 at 1:13 pm | Permalink

    Great tutorial. Excellent website. I recommend.

    Salute

  2. Ryan
    Posted July 27, 2009 at 2:56 pm | Permalink

    FYI – this doesn’t work correctly if the view has had a transform applied. For example, if you apply a transform to a UIImageView, then attempt to use this technique to save the transformed image, you actually get the original. There are functions for applying a transform to the graphics context, but finding the right order and offsets to apply them has proven much more difficult than I thought.

  3. kk
    Posted July 27, 2009 at 6:59 pm | Permalink

    Great Post.. I always read your post.

    Correct me if I am wrong. I guess this feature is already there in Iphone. when you press menu button and the button which is used to lock Iphone at the same time, it will capture the screenshot and saves it to Photos folder in Iphone.

  4. Posted July 27, 2009 at 9:53 pm | Permalink

    Hey KK,

    Yeah holding the home button and power button will take a screenshot. However this takes a screenshot of the entire screen while my example shows you how to customize that effect a bit and instead take a screenshot of any specific view you like. Thanks for reading and Happy Coding!

  5. Posted August 1, 2009 at 3:03 pm | Permalink

    Thanks a whole lot! This website has helped me so much..

  6. Posted September 7, 2009 at 12:46 am | Permalink

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    this line gives warning

    no renderInContext method found..
    it still works..but why there is warning

  7. BeckzZ
    Posted September 16, 2009 at 8:00 am | Permalink

    I get a warning too at this line…
    and the app won’t work…Getting Errormessage “GDB: Interrupted” in Simulator…

    don’t know how to fix it…

    By the way: awesome Tutorials! Keep going!

    • Posted March 18, 2010 at 9:40 pm | Permalink

      For those of you getting the warning, include the Quartz Core header:
      #import

      XCode needs this header to properly “understand” layers.

      However, I’m having the same problem as Ryan. I’m baking my UIView into an image using the renderInContext, but despite the fact that I have applied transformations to the UIView I’m still getting the original as output. I’ve even tried applying the transformations to the layer itself instead of to the view. If anyone has a solution please let me know – otherwise I’ll try to find the magic order that will apply the proper transformations to the image.

  8. MeHim
    Posted May 25, 2010 at 12:50 am | Permalink

    the code works fine but i have tried to capture textview but with no success !
    any help !

  9. Tina
    Posted August 20, 2010 at 3:28 am | Permalink

    Hi, Zane and Leo. Have you guys ever found solutions to this problem (the method isn’t working correctly when views are transfromed)? I’m working on the same thing, but couldn’t get it behave like the way I expected. Applying the transformations to the images will be my last choice…
    If anyone knows the answer please tell me, I’d appreciate it.

One Trackback

  1. By Zrzut ekranu w iPhone | appledev.pl on August 15, 2009 at 2:08 pm

    [...] się w jaki sposób zrobić programowo zrzut ekranu, to koniecznie powinniście zapoznać się z tym postem na blogu iCodeBlog. Wykop mnie teraz: These icons link to social bookmarking sites where readers [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">