UIPrintPageRenderer 是否有等价于 "renderInContext"

Is there an equivalent of "renderInContext" for UIPrintPageRenderer

您可以在图层上调用renderInContextUIPrintPageRenderer 有类似的东西吗?我基本上想从 UIPrintPageRenderer 的 PDF 文档的第一页创建一个 UIImage。除了上下文部分的实际渲染之外,我还有其余的代码。

编辑:我是不是误解了一些基本的基本概念?如果是这样,请随时给我一个快速教训。

的 Vel Genov 那里获取我的大部分信息,这是你应该做的:

下面的示例代码将类别添加到 UIPrintPageRenderer 以创建实际的 PDF 数据。

@interface UIPrintPageRenderer (PDF)
- (NSData*) createPDF;
@end

@implementation UIPrintPageRenderer (PDF)
- (NSData*) createPDF
{
    NSMutableData *pdfData = [NSMutableData data];
    UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
    [self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
    CGRect bounds = UIGraphicsGetPDFContextBounds();
    for ( int i = 0 ; i < self.numberOfPages ; i++ )
    {
        UIGraphicsBeginPDFPage();
        [self drawPageAtIndex: i inRect: bounds];
    }
    UIGraphicsEndPDFContext();
    return pdfData;
}
@end

然后,webViewDidFinishLoad()

- (void)webViewDidFinishLoad:(UIWebView *)webViewIn {
    NSLog(@"web view did finish loading");

    // webViewDidFinishLoad() could get called multiple times before
    // the page is 100% loaded. That's why we check if the page is still loading
    if (webViewIn.isLoading)
        return;

    UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
    [render addPrintFormatter:webViewIn.viewPrintFormatter startingAtPageAtIndex:0];

    // Padding is desirable, but optional
    float padding = 10.0f;

    // Define the printableRect and paperRect
    // If the printableRect defines the printable area of the page
    CGRect paperRect = CGRectMake(0, 0, PDFSize.width, PDFSize.height);
    CGRect printableRect = CGRectMake(padding, padding, PDFSize.width-(padding * 2), PDFSize.height-(padding * 2));

    [render setValue:[NSValue valueWithCGRect:paperRect] forKey:@"paperRect"];
    [render setValue:[NSValue valueWithCGRect:printableRect] forKey:@"printableRect"];

    // Call the printToPDF helper method that will do the actual PDF creation using values set above
    NSData *pdfData = [render createPDF];

    // Save the PDF to a file, if creating one is successful
    if (pdfData) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = [paths objectAtIndex:0];

        NSString *pdfPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"Purchase Order.pdf"]];

        [pdfData writeToFile:pdfPath atomically:YES];
    }
    else
    {
        NSLog(@"error creating PDF");
    }
}

PDFSize 定义为常量,设置为标准 A4 页面大小。可以对其进行编辑以满足您的需要。

#define PDFSize CGSizeMake(595.2,841.8)

以下是 Val 对代码的评价:

When webViewDidFinishLoad() gets called, the view might not be 100% loaded. A check is necessary, to see if the view is still loading. This is important, as it might be the source of your problem. If it's not, then we are good to go. There is a very important note here. Some web pages are loaded dynamically (defined in the page itself). Take youtube.com for example. The page displays almost immediately, with a "loading" screen. This will trick our web view, and it's "isLoading" property will be set to "false", while the web page is still loading content dynamically. This is a pretty rare case though, and in the general case this solution will work well. If you need to generate a PDF file from such a dynamic loading web page, you might need to move the actual generation to a different spot. Even with a dynamic loading web page, you will end up with a PDF showing the loading screen, and not an empty PDF file.

Another key aspect is setting the printableRect and pageRect. Note that those are set separately. If the printableRect is smaller than the paperRect, you will end up with some padding around the content - see code for example. Here is a link to Apple's API doc with some short descriptions for both.