is UIWebView the only way to open a pdf document on the iphone? how can i interact with the document? eg: getting the current page number?
You should read the Apple documentation about Drawing with quartz 2d. There's a section just about handling with PDF documents.
If you don't like to show a PDF in a UIWebView, you create your own view. Just subclass UIView and overwrite the method -(void)drawRect:(CGRect)rect for your custom drawing. Create a CGContextRef a draw your PDF directly in that context using the specific function of core graphics. Core Graphics provides a lot of other functions for PDF documents, like Kalle already mentioned.
If you're not really used to core graphics, it's really difficult sometimes and you probably need a lot time to get used to it, so I recommend using UIWebView to display a PDF. It relatively simple.
It's not the only way. There's a whole toolkit built in which lets you render PDF pages to a UIView. Check out:
CGPDFDocumentCreateWithURL
CGPDFDocumentGetNumberOfPages
CGPDFDocumentGetPage
CGContextDrawPDFPage
to name a few (core graphics) functions that relate to PDF rendering.
Beside UIWebView, if you want a high level interaction class, check out: UIDocumentInteractionController, QLPreviewController.
Depending on your needs, check out the accepted answer to this question.
Check Apple's ZoomingPDFViewer for a simple example: http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html
Related
I am working on a PDFReader application.I am making use of CALayer to render the pdf contents.currently one pdf page is being rendered at a time and is displayed on the visible view.I want to buffer few pages(say one previous page and one next page for example) in advance while the user is reading the current page.Can any one please suggest me a better way of achieving this buffering mechanism?Thanks in advance
You can take a look at this open source PDF viewer for iOS, it implements the features you asked about: http://www.vfr.org/2011/09/pdf-reader-viewer-v2-2/
If you want to draw some content in the background, you can look into using the Grand Central Dispatch API, and drawing using Core Graphics commands. You will need to be careful about thread safety, such as checking/waiting for the background drawing to finish before trying to the push the results to the display.
I found a quite useful post, Image manipulation and drawing using Quartz in the background threads, on ensuring that you only use thread safe commands to create your drawing context (the example creates a bitmap context, but obviously you will be looking to create a PDF context using CGPDFContextCreate or similar).
I am currently using QLPreviewController to view PDFs (250MB+) However it cannot deal with real large files. Either I get the info that not the whole file has been loaded or the whole app just dies.
I also need to customize the view which is nit possible using QLPreviewController.
What should I do? Use UIWebView instead? Or will I have to use CGContextDrawPDFPage?
Using the latter, how will I get zooming implemented?
I would go with your suggestion of using a UIWebView. Doing so will automatically give you zoom support and the UIWebView should handle loading extremely large PDF's.
If you have decided to go with Quartz, this link looks very promising for zoom support.
Does anyone know how to use core graphics to draw a pdf like in iBooks. I can already draw a pdf page using core graphics but was curious how iBooks shows a lower quality view of each page so it loads fast and then when you stay on a page longer it renders it a full quality. This makes it able to open the pdf without having to make the user wait like most magazine apps you see on ipad. Any ideas would help!
Apple have some "ZoomingPDFViewer" sample code:
http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010281
I suspect that might give you some good ideas :-)
I assume they use multiple layers, the first layer loads the pdf in low resolution and the better resolution is prepared in the background. When ready these layers are swapped.
Have a look at CGPDFDocumentRef and CATiledLayer in the documentation.
What is the best way to use the custom UI graphics on the iPhone?
I have come across CGContextDrawPDFPage and Panic's Shrinkit. Should I be using PDF's to store my vector ui graphics and loading them using CGContextDrawPDFPage to draw them.
Previously I asked what way Apple store their UI graphics and was answered crushed png. The options are I can think of are below, but I'm also interested in any other techniques...
PNG (bitmapped image)
Custom UIView drawing code (generated from Opacity)
PDF (I've not used this method, is it with CGContextDrawPDFPage?)
This question is for vector graphics only (but I guess some people may only use bitmapped?). Looking for what is standard / most effective / most efficient.
Edit: Bounty added, I'm interested to hear the process of anyone who works with UI designers, or are themselves a UI designer. And pointers on resolution independence i.e. for iPad / iPhone HD future proofing.
Many thanks
Ross
I can suggest 3 different ways, 2 of which you already mentioned:
Creating custom UIView.
Drawing in a CGLayer.
loading from PDF.
Each have their advantages, depending on what you want to do:
UIView vs CGLayer
In terms of performance (for one-time drawing) and ease of use there shouldn't be much difference between the two (there are minor differences, but nothing serious). Apparently Opacity can export source code for both (I haven't personally used it). That said, there are things you should consider before choosing:
If you have a fixed image (which your question suggests so), use CGLayer. CGLayer objects will be cached on the graphics device, so re-using them is much faster. Even if the cache is cleared, you're still using the same object for redrawing, meaning there's no need for re-creating it.
On the other hand, if you need to change your drawing as the user interacts with the app, UIView could be faster, as you have the flexibility of updating just one part of the image instead of the whole view.
CGLayer is independent of the UI. So the same code works fine for Mac/iPhone/iPad, or even for saving to files.
Conclusion: Use CGLayer, unless it's a special case.
CGLayer (In code drawing) vs PDF (loading from file)
I don't have any benchmark for this, but I expect CGLayer to be slightly faster: (1) there's no need to read a file. (2) the pdf commands should be converted to system's graphic elements, which is more or less the same as creating a CGLayer. (3) I'm not sure about how pdf pages are cached, but I don't expect it to be faster than CGLayer. Anyway, all this shouldn't make much difference unless you want optimization till the last millisec. Again, the choice should be based on your use case:
CGLayer gives you more flexibility in the code. Your only access to a pdf page is through CGContextDrawPDFPage, which means even simple tasks such as scaling/transforming the drawing will be harder.
Using PDFs on the other hand, is more flexible after finishing the code. You can simply update the pdf file with a new whenever you want, load it from the web, etc. .
Creating a pdf could be easier than coding the drawing. You can use any app you want, you don't need to worry about the API and system resources. After all, the code can output a pdf file, not the other way around.
Conclusion: If you don't need to do much with the drawing (just want to show an icon or something), go with the pdf. if you need to work on it in the app, consider CGLayer.
Of course you could always mix the approaches as you see fit: e.g. Load a pdf file, put it in a CGLayer to adjust it, draw it with a UIView where you can put a badge on it!
I stumbled over this question because I have a question about PDFs too. I'm working together with a UI designer and we are succesfully using PDFs to create UI elements. For example: For a button we have 3 PDFs for ON, OFF and the shadow. I wrote a piece of code that transformes a PDF into a UIImage. It can scale the resulting image and even colorize it to have one template for many styles of buttons. It works pretty good :)
Our problem is that we can't scale up the vector graphics without quality loss. That's why we decided to use graphics that are big enough and we only have to scale them down. But I still wonder if there's a way to scale up a PDF before drawing it to a context and create a UIImage. Here's my post.
Looking at the QuartzDemo sample application, I love the speed of the PDF rending using quartz alone (that is, without using uiwebview). However, when I'm zooming in the PDF it doesn't seem to become more clear like it does in PDF view.
Is there something that I can change to have the same effect when zooming in and out using multitouch? like manipulate the PDF transformation matrix or something?
Thanks a bunch.
--Ben
To make it zoom, and more clear,
You can use CATiledLayer. You can see the following example.
http://www.olivetoast.com/blog/hamish/simple_uiscrollview_catiledlayer_example.ot