Our DNA is written in Objective-C

Rendering PDF is easier than you thought

We all know by now that Adobe is almost as evil as …, well let’s say they pioneered a couple of functionalities that where great for the longest time. One being the PDF format which is actually totally built into OSX everywhere. On OSX you’re able to print into a PDF without having to install extra software. Also iOS comes with PDF support and today we’ll look at how we can draw a PDF in a view.

How UIWebView sees it

The first idea you might have is to use UIWebView to display PDFs which is not difficult, just get the URL, make a NSURLRequest and pass this to a web view.

_webView = [[UIWebView alloc] initWithFrame:frame];
_webView.delegate = self;
_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
// we don't want interaction, full size
_webView.scalesPageToFit = YES;
_webView.userInteractionEnabled = NO;
_webView.backgroundColor = [UIColor whiteColor];
//fileURL is an NSURL to a PDF file
[_webView loadRequest:[NSURLRequest requestWithURL:fileURL]];

But there is one drawback: you cannot really control how it will arrive on screen. For one thing, UIWebView draws a fat gray border and shadow which might somewhat mess up your UI design.

Wouldn’t it be great if you could draw the PDF somehow into a view? Yes, we can!

BSA Banner

Drawing PDF Pages

Apple provides in CoreGraphics a whole set of functions prefixed CGPDF to deal with PDFs. The easiest method for drawing the first page of a PDF file I pieced together from the documentation like this. This is a regular view where I replaced the drawRect as follows:

- (void)drawRect:(CGRect)rect
	CGContextRef ctx = UIGraphicsGetCurrentContext();
	// PDF might be transparent, assume white paper
	[[UIColor whiteColor] set];
	CGContextFillRect(ctx, rect);
	// Flip coordinates
	CGContextScaleCTM(ctx, 1, -1);
	CGContextTranslateCTM(ctx, 0, -rect.size.height);
	// url is a file URL
	CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);
	CGPDFPageRef page1 = CGPDFDocumentGetPage(pdf, 1);
	// get the rectangle of the cropped inside
	CGRect mediaRect = CGPDFPageGetBoxRect(page1, kCGPDFCropBox);
	CGContextScaleCTM(ctx, rect.size.width / mediaRect.size.width,
		rect.size.height / mediaRect.size.height);
	CGContextTranslateCTM(ctx, -mediaRect.origin.x, -mediaRect.origin.y);
	// draw it
	CGContextDrawPDFPage(ctx, page1);

The part about the mediaRect is necessary because PDF pages are typically larger than what you really see on screen. There are usually some printing, color and crop marks outside of the content area. I managed to eliminate those by changing the transformation matrix of the CGContext.

The official method in the documentation is to use CGPDFPageGetDrawingTransform, but this has a catch: it won’t scale the image to be larger than 100% and instead center it on screen. So we build our own transform, ignoring the aspect ratio because we want to fill the view with that.

If the PDF is small enough to keep in memory you could also load it into an NSData object and access individual pages from it super fast. To read from data as opposed to providing an NSURL you change the code like this:

// data is an NSData object we filled with the PDF data from file before
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFDataRef)data]);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(dataProvider);

We’re using “toll-free bridging” to simply use our NSData instance where the function is expecting a CFDataRef, and of course if we have a method called SomethingCreate then we also have to have a SomethingRelease.


Having this ability to render PDF pages int any resolution gives you a great deal of flexibility. A great tool to have in your toolchest! You might even go as far as using PDFs as your main graphics container because it can contain both vector and bitmap graphics. In fact it’s the closest you can get to vector graphics on iOS.

Now please don’t go and make yet another PDF reader with this. With iBooks 1.1 soon supporting native PDF viewing that would make no sense.

Here are a couple other ideas:

  • An app that lets you keep your musical note sheets on your iPad. You could mark sections and specify their order and then choose between classical mode (one sheet per screen) or 1-pass mode, where the sections are flattened such that you don’t have to go back to repeats, but always play from left to right. Couple that with some fancy notes OCR to have the iPad play a bar before you. Maybe use audio clues on when to know to turn the page.
  • An app that lets you EDIT PDFs on the iPad, with cut/copy/paste support so that you can paste things on the iPad into a PDF-based scrapbook.
  • Make a presentation app similar to Prezi. You would load a PDF as basis and then you would record zoom levels, viewed rectangle and rotations along a user-defined path. Give presentation to external display.
  • Use a similar technique to render rich-text documents into reports that you can e-mail from your app.
  • Make an electronic version of a magazine similar to Wired, no need for Adobe’s weird Illustrator-to-App converter that makes half a GB apps.

If you’re interesting in partnering or co-developing these ideas please e-mail me.

Categories: Recipes


  1. This is a handy thing to know. Thanks for sharing!

  2. Thanks – this is very useful.

    Just one question – how would you be able to zoom in/out of the PDF without losing quality (ie it enlarges the vector graphics). I just can’t seem to get it right.

  3. You have to draw the PDF at the higher resolution. Easiest would be to use a CATiledLayer with multiple resolutions and always draw the correct one.

  4. Hi, Thanks so much for this!

    Just wondering if you could point me at how to render a PDF just one one specific UIView, such that if that view is hidden the PDF won’t show or better if you can render straight to a CGImage.

  5. You can use any method that’s drawing in a drawRect to also draw into a bitmap context. Only difference: you have to transform the flip the coordinate system.

  6. THANK YOU for this Tutorial. I’ve been looking for something like this for sometime.

    Dan Uff

  7. My 5 hours of brain exploding was cured by the official method in the documentation having that glitch. I couldn’t figure out how to get > 100%! 🙂

  8. Thanks for the tutorial! I tried this but the PDF that was generated did not have selectable text or images. It was like the PDF created from an image. How can that be achieved?

  9. To get more than just the rendering you need to use a library like for example PSPDFKit.

  10. Thanks for the useful tutorial. I’ve extended your code into a UIImage category to render PDFs at any size to enable scaleable app assets.

    It’s on Github at: https://github.com/mindbrix/UIImage-PDF

  11. Hello everybody !!
    I would like to ask if is possible to add some animation to fold pages.
    If someone knows how it would be very useful to share it.

    Thank so Much

  12. Hi Thanks for sharing,its really helpful and i have a doubt if i have a pdf book a by doing page curl i need to see page one by one i really struggling can you please help me out….

  13. Hi , I ‘m used way draw but not display , who can help me? Thanks

  14. I hope it isn’t too late to say that this is an awesome article. You present a great alternative to the limitations of UIWebView. Thanks!

  15. good..but how we can load all pages of pdf in to the UIView…?


  1. PDF Content at Under The Bridge
  2. Get the table of contents out of a PDF file - iPhone Dev SDK Forum
  3. iCatalog.framework brings Digital Catalogs to Life on iPad @ Cocoanetics
  4. thetawelle » Blog Archiv » Using UIImage-PDF category for @#x resolution independence coping with ever increasing Apple iDevice Size Fragmentation - frontier of science, technology & future

Leave a Comment

%d bloggers like this: