How to draw on pdf page with PDFKit - ios

I’m currently working on a project and I need to generate a PDF based on a bunch of information the user had entered.
I'm using PDFKit, I managed to create a PDFView and add a PDFDocument to it. My problem is that I couldn't really find a way to draw on the document's pages using PDFKit. I don't want to add annotations, I want to draw tables and texts inside that table's cells.
I've found some examples to do that but all of them were not complete and you need to have some knowledge to really understand them. I've also found some examples using Quartz and Core Graphics but I don't know if I can apply it to PDFKit.
I need only an example of drawing a line using PDFKit.
Thanks.

All you need is create pdfData:
-(NSMutableData *)createPDFData {
// 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
CGRect bounds = self.bounds;
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
UIGraphicsBeginPDFPageWithInfo(bounds, nil);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
[self drawBottomRect];
[self drawImageView:self.ivBackground];
// draw labels by section
[self drawLabel:self.walletName];
currentContext = UIGraphicsGetCurrentContext();
// remove PDF rendering context
UIGraphicsEndPDFContext();
return pdfData;
}
Example how to draw image view:
-(void) drawImageView: (UIImageView*) imageView
{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGRect frameRect = [imageView convertRect:imageView.bounds toView:self];
CGContextTranslateCTM(currentContext, frameRect.origin.x,frameRect.origin.y);
[imageView.layer renderInContext:currentContext];
CGContextTranslateCTM(currentContext, -frameRect.origin.x,- frameRect.origin.y);
}
Save PDF data as file.

Related

Core plot graph is rendered as black box when converting into pdf

I my application used Core Plot to render graphs, and finally there is a need to create a pdf file, there should be this graph, but when it is saved to pdf file, instead of graph I see black box.
The method I use to create a pdf:
UIGraphicsBeginPDFContextToFile(outputPath, CGRectZero, nil);
for(UIView *view in views) {
UIGraphicsBeginPDFPageWithInfo(view.bounds, nil);
CGContextRef pdfContext = UIGraphicsGetCurrentContext();UIGraphicsBeginPDFContextToFile
[view.layer renderInContext:pdfContext];
}
UIGraphicsEndPDFContext();
Could someone help how to make it render properly?
As a temporary solution before creating a pdf I convert graph to image and put it on the top of it as a result pdf is rendered properly, Is there any more elegant solution?
Edited:
I applied the above advice the code looks like this:
if([child isKindOfClass:[CPTGraphHostingView class]]) {
CGContextTranslateCTM(pdfContext, child.center.x, child.center.y);
CGAffineTransform transform = CGAffineTransformMakeRotation(0);
transform.d = -1;
CGContextConcatCTM(pdfContext, transform);
CGContextTranslateCTM(pdfContext,
child.bounds.size.width * 0.05,
-child.bounds.size.height * 0.75);
CPTLayer *layer = (CPTLayer *)((CPTGraphHostingView *)child).hostedGraph;
[layer layoutAndRenderInContext:pdfContext];
}
Result on UI:
and as a result is pdf:
Are you using any fills with partially transparent colors? The alpha channel doesn't render into PDF. This is a long-standing issue with the Apple PDF frameworks.

renderInContext no longer working in xCode 8

I've been working on an app where I have a UIView that needs to be printed via AirPrint. To accomplish this I first fill out all the details in the view and then pass it to the below code to make a pdf out of before printing it.
In Xcode 7 everything was working fine. Since I did the update to Xcode 8, the view doesn't render to the correct size any more using renderInContext.
- (NSMutableData *)createPDFDataFromUIView:(UIView *)aView {
NSMutableData *pdfDataObject=[NSMutableData data];
// create a PDF-based graphics context with mutable data object as the target
UIGraphicsBeginPDFContextToData(pdfDataObject, [aView bounds], nil);
// mark the beginning of a new page
UIGraphicsBeginPDFPage();
// get the CGContextRef for our PDF drawing
CGContextRef pdfContext= UIGraphicsGetCurrentContext();
// render the UIView’s layer into the PDF context
[[aView layer] renderInContext:pdfContext];
// end the PDF context
UIGraphicsEndPDFContext();
return pdfDataObject;
}
Any help would be appreciated.

how to insert textField with tableView into PDF file

I'm using code to create a PDF File. Works.
But: I want my whole UITableView(I need to scroll) in my PDF File and not just the part of the view which is currently displayed on screen.
laso i need to add three textField to the same file PDF
this must be take all the content of view (three textField and the tableView with all cell) because this is an invoice
Is there a way to achieve this?
i use the following code
- (void)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, self.view.bounds, nil);
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
[self.view.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];
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
}
but the problem it take as image to the view and the remaining cells for tableView didn't include PDF file
UIView *viewToRender = self.tableView;
CGPoint contentOffset = self.tableView.contentOffset;
UIGraphicsBeginImageContext(viewToRender.bounds.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// KEY: need to translate the context down to the current visible portion of the tablview
CGContextTranslateCTM(ctx, 0, -contentOffset.y);
[viewToRender.layer renderInContext:ctx];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
try this

Create PDF from UIScrollView Objective C

this question has been posted before (Creating PDF from UIScrollView in iphone app) and the code I am using is from here.
Here is the code
-(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];
documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
}
Setup: I have a UIScrollView, inside is a UIView. I want to save the entire UIView (950,500px) and it's in a space (the UIScrollView size) of (520,500). The PDF being generated is only the size of UIScrollView (520,500)
I read the answer but he apparently changed the code but it doesn't work for me. I've been trying to fix this all day.
I'm a beginner so please indicate anything I should add to my question that I missed. Thank you.
PS - this is an iPad app.
The context should have the size of the scrollview's content size, not the bounds.
Then you need to temporarily resize the scrollview to its content size, render it in the PDF context, and restore the size of the scrollview to its original size.
UIGraphicsBeginPDFContextToData(pdfData, (CGRect){0,0, scrollView.contentSize}, nil);
CGRect origSize = scrollView.frame;
CGRect newSize = origSize;
newSize.size = scrollView.contentSize;
[scrollView setFrame:newSize];
[scrollView.layer renderInContext:pdfContext];
[scrollView setFrame:origSize];
Check ScrollViewToPDF example and you will understand what you need to do.
It uses same scrollview's layer renderInContext but here PDF is created according to your requirement such as one page PDF or multiple page PDF
Note : It captures all visible as well as invisible part of scrollView
If anyone was wondering, I found how to fix this.
Since my UIView is IN a UIScrollView, and I use another class for the UIView, when I call the method and chose the parameter aView, I just put in self.
So in my UIView class, when I want the PDF to be generated I type in
[self createPDFfromUIView:self saveToDocumentsWithFileName:UIViewPDF];

iPad UIView to PDF - low resolution

I have an app in which PDF is shown in UIWebView, and on top of that I put some UITextFields that need to be filled. The problem is when I generate new PDF from these views, PDF (from UIWebView) resolution stays ok, but text from UITextFields are fuzzy. How to fix that?
I have the following code to generate PDF:
// 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();
You have to upscale your View. Have a look at this, he gives a nice explanation:
http://cadabracorp.com/blog/2012/09/26/creating-printing-and-emailing-high-resolution-pdfs-in-ios/

Resources