Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Convert UIView to PDF within iOS?

There are a lot of resources about how to display a PDF in an App's UIView. What I am working on now is to create a PDF from UIViews.

For example, I have a UIView, with subviews like Textviews, UILabels, UIImages, so how can I convert a big UIView as a whole including all its subviews and subsubviews to a PDF?

I have checked Apple's iOS reference. However, it only talks about writing pieces of text/image to a PDF file.

The problem I am facing is that the content I want to write to a file as PDF is a lot. If I write them to the PDF piece by piece, it is going to be huge work to do. That's why I am looking for a way to write UIViews to PDFs or even bitmaps.

I have tried the source code I copied from other Q/A within Stack Overflow. But it only gives me a blank PDF with the UIView bounds size.

-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename {     // Creates a mutable data object for updating with binary data, like a byte array     NSMutableData *pdfData = [NSMutableData data];      // Points the pdf converter to the mutable data object and to the UIView to be converted     UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);     UIGraphicsBeginPDFPage();      // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData     [aView drawRect:aView.bounds];      // remove PDF rendering context     UIGraphicsEndPDFContext();      // Retrieves the document directories from the iOS device     NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);      NSString* documentDirectory = [documentDirectories objectAtIndex:0];     NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];      // instructs the mutable data object to write its context to a file on disk     [pdfData writeToFile:documentDirectoryFilename atomically:YES];     NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); } 
like image 279
Cullen SUN Avatar asked Mar 26 '11 15:03

Cullen SUN


2 Answers

Note that the following method creates just a bitmap of the view; it does not create actual typography.

(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename {     // Creates a mutable data object for updating with binary data, like a byte array     NSMutableData *pdfData = [NSMutableData data];      // Points the pdf converter to the mutable data object and to the UIView to be converted     UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);     UIGraphicsBeginPDFPage();     CGContextRef pdfContext = UIGraphicsGetCurrentContext();       // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData      [aView.layer renderInContext:pdfContext];      // remove PDF rendering context     UIGraphicsEndPDFContext();      // Retrieves the document directories from the iOS device     NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);      NSString* documentDirectory = [documentDirectories objectAtIndex:0];     NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];      // instructs the mutable data object to write its context to a file on disk     [pdfData writeToFile:documentDirectoryFilename atomically:YES];     NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); } 

Also make sure you import: QuartzCore/QuartzCore.h

like image 191
casillic Avatar answered Sep 20 '22 00:09

casillic


Additionally, if anyone is interested, here is the Swift 3 code:

func createPdfFromView(aView: UIView, saveToDocumentsWithFileName fileName: String) {     let pdfData = NSMutableData()     UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil)     UIGraphicsBeginPDFPage()      guard let pdfContext = UIGraphicsGetCurrentContext() else { return }      aView.layer.render(in: pdfContext)     UIGraphicsEndPDFContext()      if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {         let documentsFileName = documentDirectories + "/" + fileName         debugPrint(documentsFileName)         pdfData.write(toFile: documentsFileName, atomically: true)     } } 
like image 30
retrovius Avatar answered Sep 19 '22 00:09

retrovius