Spent more time today exploring the [NSString drawInRect:] method to see if I could get it to work, and I now have a working solution. The key is that you have to push the graphics context onto the stack. Below is how it works:
So, the above code block pushes the context onto the stack, reverses the coordinates so that the text is drawn correctly, and then uses the drawInRect: withFont: method to draw the text, and finally calls the UIGraphicsPopContext() method.
It's important to note that each time you call UIGraphicsPushContext(context); you must also call the pop context method, otherwise you'll be left with nothing.
Thanks to decay for pushing me to investigate this more and enjoy everyone!
Spent more time today exploring the [NSString drawInRect:] method to see if I could get it to work, and I now have a working solution. The key is that you have to push the graphics context onto the stack. Below is how it works:
So, the above code block pushes the context onto the stack, reverses the coordinates so that the text is drawn correctly, and then uses the drawInRect: withFont: method to draw the text, and finally calls the UIGraphicsPopContext() method.
It's important to note that each time you call UIGraphicsPushContext(context); you must also call the pop context method, otherwise you'll be left with nothing.
Thanks to decay for pushing me to investigate this more and enjoy everyone!
Your welcome, Daniel. Actually, I only call UIGraphicsPushContext() at the very end of the document. In between, I also use [UIImage drawInRect:] to stick pictures in the document, as well as drawing a line graph. I am generating PDFs on the fly, sometimes in the 17-20 page range. My app that uses this will be submitted to Apple tomorrow actually.
Thanks for the great tutorial. It helps me a lot. Finally I need to display the € currency symbol. In stead of Euro symbol, the pDF file shows some other unrecognized characters. Could you help me in this regard......
You'd have to use the mailto: url scheme to open up mail.app, and, on non-jailbroken phones it is impossible to use the attachment paramter of mailto:, so you'l have to write an SMTP client.
Spent more time today exploring the [NSString drawInRect:] method to see if I could get it to work, and I now have a working solution. The key is that you have to push the graphics context onto the stack. Below is how it works:
So, the above code block pushes the context onto the stack, reverses the coordinates so that the text is drawn correctly, and then uses the drawInRect: withFont: method to draw the text, and finally calls the UIGraphicsPopContext() method.
It's important to note that each time you call UIGraphicsPushContext(context); you must also call the pop context method, otherwise you'll be left with nothing.
Thanks to decay for pushing me to investigate this more and enjoy everyone!
I know this is a late addition to your original post but I'm in desperate need of some help with the iPhone PDF stuff. I'm looking for the correct way to use a couple of CGPDF functions namely:
CGPDFDocumentGetPage and CGPDFPageGetPageNumber
I am trying to set up a bookmark for a locally loaded pdf document with multiple pages.
I am trying to load the bookmarked page like so:
I don't know how do to create a CGContextRef in CGPDFContext to show a NSString. I'm trying with UIGraphicsGetCurrentContext(), but this function return nil.
Generate a pdf file from current contents of UIWebView
Does anybody know how to take the current contents of a UIWebView and save them into a pdf file?
Using this tutorial as a starting point, I took out everything between CGContextBeginPage and CGContextEndPage.
I first tried
Code:
// webView is my passed in UIWebView *
[webView.layer drawInContext:pdfContext];
The documentation says that UIView's have a layer property of type CALayer *, and CALayer has a drawInContext method. Yet I get a warning that there is no drawInContext method here, and nothing happens when I run it.
Well the good news is that I figured it out. The problem was I was using drawInContext, while renderInContext is the one to use....
Code:
// PDF page drawing expects a Lower-Left coordinate system, so we flip the coordinate system
// before we start drawing.
CGContextTranslateCTM(pdfContext, 0.0, pageRect.size.height);
CGContextScaleCTM(pdfContext, 1.0, -1.0);
// webView is my UIWebView component
[webView.layer renderInContext:pdfContext];
The bad news is that this just produces a screen sized bitmap in the pdf, so not that useful.
Quote:
Originally Posted by pmattf
Does anybody know how to take the current contents of a UIWebView and save them into a pdf file?
Using this tutorial as a starting point, I took out everything between CGContextBeginPage and CGContextEndPage.
I first tried
Code:
// webView is my passed in UIWebView *
[webView.layer drawInContext:pdfContext];
The documentation says that UIView's have a layer property of type CALayer *, and CALayer has a drawInContext method. Yet I get a warning that there is no drawInContext method here, and nothing happens when I run it.
Is everybody on this thread aware of the fact that any pdf's produced by the iPhone sdk which have text in them are not in fact valid in terms of the pdf spec? They work fine on the iPhone itself or MacOS, but on some Windows and other viewers they appear blank or garbled. For example, if you email one to a gmail acount, and look at it with gmail's inline viewer, it shows up as blank. If you then save it to a Mac, it looks fine.
Here is a thread talking about the issue...
orum/iphone-sdk-development/15505-pdf-font-problem-cant-get-cids-glyphs.html
I think that error is usually generated when you try to call a method on an object which as already been released and reclaimed by the system.
So maybe you are releasing something too soon?
If you run it in debug mode, you should get a stack trace when you hit the error, then you should be able to see what method call is causing the error, and hence what object has the problem.
Quote:
Originally Posted by apiphone
I am getting an error while creating the pdf files.
It says : GDB: Program received signal EXC_BAD_ACCESS
I'm using the same code and it is creating a blank pfd file.
Why????
I'm trying to understand what's not working but I start programming one week ago.... I'm a totally noob!
Thanks anyway for the code, I'm learning a lot from this.
Well the good news is that I figured it out. The problem was I was using drawInContext, while renderInContext is the one to use....
Code:
// PDF page drawing expects a Lower-Left coordinate system, so we flip the coordinate system
// before we start drawing.
CGContextTranslateCTM(pdfContext, 0.0, pageRect.size.height);
CGContextScaleCTM(pdfContext, 1.0, -1.0);
// webView is my UIWebView component
[webView.layer renderInContext:pdfContext];
The bad news is that this just produces a screen sized bitmap in the pdf, so not that useful.
Hi pmattf,
Did you ever manage to get this to work and save correctly instead of a bitmap in the pdf??
Trying to figure this out aswell.
Hi pmattf,
Did you ever manage to get this to work and save correctly instead of a bitmap in the pdf??
Trying to figure this out aswell.
Cheers!!
No, there is no way to get anything out of the UIWebView other than a bitmap. And I could not figure out a way to get one out that is big enough to be useful (though I would not rule out the possibility that you could get a larger one than I did).
In MacOS it is trivial, because there is pdf rendering built into the print system (i.e. the Save as PDF in the print dialog). So you can easily take most anything, and render it out as a pdf.
But as far as I could determine, there is no existing code that runs on the iPhone that takes html and converts it to pdf. You would either need to find some C code that does this, and get it running on iPhone, or do it via a web service (there are plenty of options for libraries that would run on a web server to do it).
What I ended up doing is vastly simplifying the formatting I was doing, so that I could just render it out as strings and images with the pdf functions that the iPhone does have. But per my post a couple up, the resulting pdf's are not actually valid, and will not work everywhere.
I have written an intro to PDF tutorial for those that are interested in PDF interactivity within your iPhone apps. This first tutorial, shows how to simply create a PDF that contains an image, some text and a border around the page.
Ok, on to the goods! There are two custom methods in the PDFViewController.m file that you will be looking at mostly. The first is CreatePDFFile. This method does exactly what it says - creates a PDF file. The second method is called createPDF, and is an IBAction method hooked to an UIButton in IB. Upon touching the button this method calls our CreatePDFFile method.
Important - there is no output after clicking the button, meaning you will not see the resulting PDF displayed on the phone. I can create a second tutorial for that purpose, but it seemed like most people were only interested in the creation of the file.
In order to view the resulting PDF go to:
Users/YourUserName/Library/Application Support/iPhone Simulator/User/Applications
In this directory sort by Date Modified. If the example project here was the last app that you ran it will be at the top of this directory. Simply navigate to the documents directory of the PDF example app and you will be able to see the PDF it creates.
Let me know if you have any questions!
P.S. So it seems that the example project was larger than the allowed size for attachments. I will get the whole project up on the web for download soon, but in the meantime I have included the class files which is all you should need.
Great! Thanks for your tutorial...I am sure this will help us all at Dev SDK forum. CHeers,
This tutorial was so much help so thank you so much for that.
I am currently trying to create a multi page pdf, which is simple enough except that I have a string of text entered by the user (like a note) and now I need to divide this text into a string for each page.
But I cannot figure out how to do this! I cannot simply get a substring to index whatever, because there is no way of getting the index, and it doesn't seem possible to know which characters you draw in [string drawInRect:rect].
The sizeWithFont methods (hidden in the documentation for NSString UIKit Additions, not in NSString itself) can tell you how much vertical space your string will take up for a given font in a given width box. You basically need to find the longest substring of your string which ends at a word boundary that returns the height you want for a single page. That could be done brute force, by starting with your entire string, testing it, chopping off one word from the end, testing that, etc. Or try to get clever, and do it like a binary search or something.
Quote:
Originally Posted by CodeDropAccount
This tutorial was so much help so thank you so much for that.
I am currently trying to create a multi page pdf, which is simple enough except that I have a string of text entered by the user (like a note) and now I need to divide this text into a string for each page.
But I cannot figure out how to do this! I cannot simply get a substring to index whatever, because there is no way of getting the index, and it doesn't seem possible to know which characters you draw in [string drawInRect:rect].
Thanks for making the tutorial...can you please help in writing a sample code presenting zoom-able single pages with a previous-next page function.
Thanks in advance
Quote:
Originally Posted by danielb21
Good afternoon everyone!
I have written an intro to PDF tutorial for those that are interested in PDF interactivity within your iPhone apps. This first tutorial, shows how to simply create a PDF that contains an image, some text and a border around the page.
Ok, on to the goods! There are two custom methods in the PDFViewController.m file that you will be looking at mostly. The first is CreatePDFFile. This method does exactly what it says - creates a PDF file. The second method is called createPDF, and is an IBAction method hooked to an UIButton in IB. Upon touching the button this method calls our CreatePDFFile method.
Important - there is no output after clicking the button, meaning you will not see the resulting PDF displayed on the phone. I can create a second tutorial for that purpose, but it seemed like most people were only interested in the creation of the file.
In order to view the resulting PDF go to:
Users/YourUserName/Library/Application Support/iPhone Simulator/User/Applications
In this directory sort by Date Modified. If the example project here was the last app that you ran it will be at the top of this directory. Simply navigate to the documents directory of the PDF example app and you will be able to see the PDF it creates.
Let me know if you have any questions!
P.S. So it seems that the example project was larger than the allowed size for attachments. I will get the whole project up on the web for download soon, but in the meantime I have included the class files which is all you should need.