从 UIScrollView 创建 PDF(第一页之后的页面是空白的)

Create PDF from UIScrollView (pages after 1st are blank)

我一直在研究堆栈,google 试图找到正确的方法来解决这个问题,任何帮助都会很棒。

我可以在 PDF 中呈现第一页,但其他所有页面都是空白的。

我在故事板的视图控制器上有一个 UIScrollView。我在视图控制器的 viewDidLoad 方法中将内容动态加载到该滚动视图中。添加任何项目后,我记录它的高度,然后相应地设置滚动视图的内容大小高度,所以滚动视图很好。它的内容宽度设置为 612

然后我调用一个函数来创建一个 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)

}

为什么第一页之后的数据没有被呈现?我得到正确的页数,只有第一页有任何数据。谢谢(我是新人,非常感谢您抽出时间来看)。

您应该使用以下函数将 PDF 上下文的转换矩阵 (CTM) 转换为与滚动 UIScrollView 实例相同的量:

CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -offsetForScroll);

那么您对 ​​renderInContext 的调用应该会正常运行。

您可以通过查看以下示例来了解此方法的实际效果,该示例截取特定偏移处可见区域的屏幕截图并将其保存到图像中:

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();

另外,你的if条件不正确。将 else if pageCount > 1 更改为 else if pageCount >= 1 以便它不会跳过页码 1.

通常我使用以下代码从我的 UIView 制作 PDF 文件。尝试一下可能会有帮助

 // 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();

例如

-(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;
}