Reputation: 6800
I've been around the block on stack and google trying to get the right way to do this ironed out, any help would be great.
I can render the first page in a PDF but every other page is just blank.
I have a UIScrollView on a view controller in storyboard. I dynamically load content into that scroll view in my view controller's viewDidLoad method. After any item is added I record it's height and then set the content size height of the scroll view accordingly, so the scroll view is fine. It's content width is set to 612
Then I call a function to create a PDF:
func createPDF() {
let pdfData = NSMutableData()
let scrollHeigt = scrollViewForContent.contentSize.height
let rawNumberOfPages = scrollHeigt / CGFloat(792)
let numberOfPages = Int(ceil(rawNumberOfPages))
var pageNumber = Int()
let pageSize = CGSizeMake(612, 792)
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil)
let pdfContext : CGContextRef = UIGraphicsGetCurrentContext()
do {
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil)
if pageNumber < 1 {
scrollViewForContent.layer.renderInContext(pdfContext)
} else if pageNumber >= 1 {
let offsetForScroll = CGFloat(pageNumber * 792)
scrollViewForContent.setContentOffset(CGPointMake(0, offsetForScroll), animated: false)
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -offsetForScroll)
scrollViewForContent.layer.renderInContext(pdfContext)
}
pageNumber++
}
while pageNumber < numberOfPages
UIGraphicsEndPDFContext()
let tempDir = NSTemporaryDirectory()
let tempDirWithFilename = tempDir.stringByAppendingPathComponent("test1.pdf")
pdfData.writeToFile(tempDirWithFilename, atomically: true)
let aURL : NSURL = NSURL(fileURLWithPath: tempDirWithFilename)!
let objectsToShare : NSArray = [aURL]
let activityVc = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
self.presentViewController(activityVc, animated: true, completion: nil)
}
How come the data for anything past the first page isn't being rendered? I get the correct number of pages, only the first page has any of the data. Thank you (I'm new and really appreciate you taking the time to look).
Upvotes: 2
Views: 2063
Reputation: 2041
Normally I use following code to make PDF file from my UIView. Try it may be it is helpful
// Creates a mutable data object for updating with binary data, like a byte array
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData(pdfData, view.bounds, nil);
//Start your first page
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
//Now render view with subviews to PDF
[view.layer renderInContext:pdfContext];
// Close PDF Render
UIGraphicsEndPDFContext();
For Example
-(NSMutableData *)createPDFDatafromUIView:(UIView*)aView
{
// 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
Markup *markup;
for(UIView *view in [aView subviews])
{
if([view isKindOfClass:[Markup class]])
{
markup=(Markup*)view;
break;
}
}
UIGraphicsBeginPDFContextToData(pdfData, markup.bounds, nil);
for(UIView *view in [aView subviews])
{
if([view isKindOfClass:[Markup class]])
{
markup=(Markup*)view;
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
[markup.layer renderInContext:pdfContext];
}
}
// remove PDF rendering context
UIGraphicsEndPDFContext();
return pdfData;
}
Upvotes: 0
Reputation: 5409
You should translate the transformation matrix (CTM) of the PDF context the same amount you scroll the UIScrollView
instance using the function below:
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -offsetForScroll);
Then your call to renderInContext
should function properly.
You can see this method in action by looking at the following example that takes the screenshot of the visible area at a particular offset and saves it into an image:
scrollViewForContent.setContentOffset(CGPoint(x: 0, y: shiftAmount), animated: false)
UIGraphicsBeginImageContextWithOptions(scrollViewForContent.frame.size, true, 0);
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -scrollViewForContent.contentOffset.y);
scrollViewForContent.layer.renderInContext(UIGraphicsGetCurrentContext())
let img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Also, your if conditions are incorrect. Change else if pageCount > 1
to else if pageCount >= 1
so that it doesn't skip the page number 1.
Upvotes: 3