Printing shinobi chart into PDF

2019-07-17 05:26发布

问题:

I have several shinobicharts in my App that I want to print into a PDF file. Everything else, like normal views, labels and images work fine, even the grid, legend and gridlabels are displayed. The only thing missing are the series. So basically I get an empty chart printed into the PDF file.

I print the PDF as follows:

NSMutableData * pdfData=[NSMutableData data];
PDFPage1ViewController *pdf1 = [self.storyboard instantiateViewControllerWithIdentifier:@"PDF1"];
pdf1.array1 = array1;
pdf1.array2 = array2;
pdf1.array3 = array3;
pdf1.array4 = array4;
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero,nil);
CGContextRef pdfContext=UIGraphicsGetCurrentContext();
UIGraphicsBeginPDFPage();
[pdf1.view.layer renderInContext:pdfContext];
UIGraphicsEndPDFContext();

The exact same code from PDF1PageViewController draws beautiful charts in a normal viewController, not missing the series. The arrays contain the data which should be displayed.

[EDIT]

This code did it for me:

UIGraphicsBeginImageContextWithOptions(pdf1.view.bounds.size, NO, 0.0);
[pdf1.view drawViewHierarchyInRect:pdf1.view.bounds afterScreenUpdates:YES];
UIImage *pdf1Image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *pdf1ImageView = [[UIImageView alloc] initWithImage:pdf1Image];
[pdf1ImageView.layer renderInContext:pdfContext];

Although the activity wheel stops spinning after drawViewHierarchyInRect and the label displaying the current page being rendered also stops updating. Anyone knows how to fix this?

回答1:

The reason that you're having this problem is that the series part of the charts are rendered in openGLES, and therefore don't get rendered as part of renderInContext:.

You have a couple of options which you can investigate using. the first is the addition of some snapshotting methods on UIView in iOS7. If you're app can be restricted to iOS7 only, then snapshotViewAfterScreenUpdates: will return you a UIView which is a snapshot of the content. I think that the following (untested) code will work:

UIGraphicsBeginPDFPage();
UIView *pdfPage = [pd1.view snapshotViewAfterScreenUpdates:YES];
[pdfPage.layer renderInContext:pdfContext];
UIGraphicsEndPDFContext();

There are more details on this approach on the ShinobiControls blog at http://www.shinobicontrols.com/blog/posts/2014/02/24/taking-a-chart-snapshot-in-ios7

If restricting your app to iOS7 isn't an option then you can still achieve the result you want, but it is a little more complicated. Luckily, again, there is a blog post on the ShinobiControls blog (http://www.shinobicontrols.com/blog/posts/2012/03/26/taking-a-shinobichart-screenshot-from-your-app) which describes how to create a UIImage from a chart. This could easily be adapted to render into your PDF context, rather than the image context created in the post. There is an additional code snippet to accompany the post, available on github: https://github.com/ShinobiControls/charts-snippets/tree/master/iOS/objective-c/screenshot.

Hope this helps

sam