Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIWebView到PDF的Objective-C问题_Ios_Objective C_Pdf_Uiwebview - Fatal编程技术网

Ios UIWebView到PDF的Objective-C问题

Ios UIWebView到PDF的Objective-C问题,ios,objective-c,pdf,uiwebview,Ios,Objective C,Pdf,Uiwebview,我这里有一个方法,它将我的UIWebView转换成PDF,并且运行良好。但当我打印出这个PDF或通过电子邮件发送时,它就被切断了。如果我将UIWebView的大小增加到900或1024,则只生成我设置的UIWebView的大小(宽度:688&高度:577),比如说我的PDF为空。我的UIWebView大于577,但在我的应用程序中,我可以滚动 这里是方法 -(void)webViewDidFinishLoad:(UIWebView *)webViewPDF { CGRect origfr

我这里有一个方法,它将我的UIWebView转换成PDF,并且运行良好。但当我打印出这个PDF或通过电子邮件发送时,它就被切断了。如果我将UIWebView的大小增加到900或1024,则只生成我设置的UIWebView的大小(宽度:688&高度:577),比如说我的PDF为空。我的UIWebView大于577,但在我的应用程序中,我可以滚动

这里是方法

-(void)webViewDidFinishLoad:(UIWebView *)webViewPDF
{
    CGRect origframe = webViewPDF.frame;
    NSString *heightStr = [webViewPDF stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; // Get the height of our webView
    int height = [heightStr intValue];

    CGFloat maxHeight   = kDefaultPageHeight - 2*kMargin;
    int pages = floor(height / maxHeight);

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];

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

    UIGraphicsBeginPDFContextToFile(self.pdfPath, CGRectZero, nil);

    for (int i = 0; i < pages; i++)
    {
        if (maxHeight * (i+1) > height) {
            CGRect f = [webViewPDF frame];
            f.size.height -= (((i+1) * maxHeight) - height);
            [webViewPDF setFrame: f];
        }

        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
        CGContextRef currentContext = UIGraphicsGetCurrentContext();

        CGContextTranslateCTM(currentContext, kMargin, kMargin);

        [webViewPDF.layer renderInContext:currentContext];
    }

    UIGraphicsEndPDFContext();

    [webViewPDF setFrame:origframe];
    [[[webViewPDF subviews] lastObject] setContentOffset:CGPointMake(0, 0) animated:NO];
}
这是我的共享按钮:

- (IBAction)Share:(id)sender {

    NSData *pdfData = [NSData dataWithContentsOfFile:self.pdfPath];

    UIActivityViewController * activityController = [[UIActivityViewController alloc] initWithActivityItems:@[pdfData] applicationActivities:nil];

    UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:activityController];

    [popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width - 36, 60, 0, 0)inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

}

我以前使用UIPrintPageRenderer做过这件事。这是一种从UIWebView创建PDF的更为简单的方法,到目前为止,它对我来说工作得很好。我已经用Xcode 6和iOS 8.2测试了这个解决方案。此外,尝试打印生成的PDF,所有内容都打印得很好

当我阅读OP时,我对不同的页面大小做了一些测试,看看是否可以得到一个空白的PDF。我确定了几个关键项目,它们可能会生成一个空白的PDF文件。我已经在代码中识别了它们

调用webViewDidFinishLoad()时,视图可能没有100%加载。需要进行检查,以查看视图是否仍在加载。这很重要,因为它可能是您问题的根源。如果不是,那我们就可以走了。这里有一个非常重要的提示。某些web页面是动态加载的(在页面本身中定义)。以youtube.com为例。页面几乎立即显示,并显示“加载”屏幕。这将欺骗我们的web视图,它的“isLoading”属性将设置为“false”,而网页仍在动态加载内容。这是一个非常罕见的情况,但在一般情况下,这个解决方案将工作得很好。如果需要从这种动态加载网页生成PDF文件,可能需要将实际生成的PDF文件移动到其他位置。即使使用动态加载网页,您最终也会看到一个显示加载屏幕的PDF,而不是一个空的PDF文件

另一个关键方面是设置printableRect和pageRect。请注意,这些是单独设置的。如果printableRect比paperRect小,那么最终将在内容周围填充一些内容-例如,请参见代码。下面是苹果公司API文档的一部分,对两者都有一些简短的描述

下面的示例代码向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
PDFSize定义为一个常量,设置为标准A4页面大小。可以对其进行编辑以满足您的需要

#define PDFSize CGSizeMake(595.2,841.8)

为了在内存中创建PDF文件,需要绘制
UIWebBrowserView
实例的层,该层位于
UIWebView
scrollView
下面。为此,请尝试更改
renderInContext:
调用以下方法:

UIView* contentView = webViewPDF.scrollView.subviews.firstObject;
[contentView.layer renderInContext:currentContext];
此外,如果您将iOS>=7.0作为目标,则可以避免使用
renderInContext:
,并使用其中一个
SnapshotViewAfterScreenUpdate:

或者
drawViewHierarchyInRect:AfterScreen更新:
methods.

那么这与Objective-C有什么关系呢?这个方法是客观的,因为你的代码恰好在Objective-C中。任何人都可以看到。但问题不在于Objective-C。无论答案是什么,无论您使用的是Objective-C、Swift、AppleScript还是其他什么,答案都是一样的。您是否尝试过将UIWebview的边界设置为PDF格式的页面大小,然后滚动UIWebview,以便在调用layer.renderInContext之前显示该页面所需的确切片段?UIWebview可能会优化绘图,以便它只将在任何给定时间可见的部分内容绘制到其所在的层。我不明白@davidvandriesche,您能给出一个答案吗?我将把它放在我的方法中的什么位置?替换您已有的调用:
[webViewPDF.layer renderInContext:currentContext]尝试从对象[0]插入nil对象。
我已经用我的共享按钮更新了我的问题dfsize是一个常量。它基本上定义了页面大小。我会在这里使用一些标准的东西,这就是为什么我把它设置为A4。您可以修改它以获得所需的页面大小。就您的share()操作而言,当PDF在您定义的路径上不可用时,您将遇到问题。有几件事你可以尝试-确保你使用相同的路径来保存和共享文件。另一件事,这一点更重要,确保PDF文件是实际创建的,并且在该路径中可用。我测试了我这边的操作,但我没有崩溃。@VelGenov:我正在用同样的方法为Microsoft文档创建PDF。但在这里,创建的PDF具有灰色背景。我可以更改它吗?@MansiPanchal,此线程特定于在iOS中查看PDF。在Microsoft环境中创建PDF时,您可能会看到另一个问题。你将不得不为此单独发布一个问题,并添加一些细节。谢谢
#define PDFSize CGSizeMake(595.2,841.8)
UIView* contentView = webViewPDF.scrollView.subviews.firstObject;
[contentView.layer renderInContext:currentContext];