【问题标题】:Generate multipage PDF from NSAttributedString swift 3从 NSAttributedString swift 3 生成多页 PDF
【发布时间】:2017-06-13 09:17:21
【问题描述】:

我有一个很长的NSAttributedString,我正在尝试将其绘制为 PDF,使用 draw func 制作单页 PDF 非常简单:

func createPDFFilea(atext: NSAttributedString) -> NSMutableData {

    let pdfData = NSMutableData()
    let paperRect = CGRect(x: 0, y: 0, width: 595.2, height: 841.8);
    UIGraphicsBeginPDFContextToData(pdfData, paperRect, nil)
    UIGraphicsBeginPDFPage()

    atext.draw(in: paperRect)
    UIGraphicsEndPDFContext()

    return pdfData
}

但是如果文本超过paperRect就会丢失,如何管理呢?

PS。这里有一个类似的解决方案,带有一个简单的 NSString 用于 obj-C http://www.coderzheaven.com/2016/09/07/create-pdf-in-ios/ 但我不知道在 Swift 中得到它,而且官方的苹果文档似乎也只适用于 obj-C https://developer.apple.com/library/content/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GeneratingPDF/GeneratingPDF.html

【问题讨论】:

  • 我最近不得不做同样的事情 - 我有一个多节表格要打印,它可能分成多个页面。我的解决方案是一次向 UIWebView 添加一行,并使用“webViewDidFinishLoad”检查页面大小——一旦超过页面,我使用以前的 html 文本,并创建一个新的 UIWebView。完成所有网页后,创建多页 PDF 是一项简单的任务

标签: ios pdf swift3


【解决方案1】:

我终于设法将 obj-C 代码转换为 swift3

    func createPDFwithAttributedString(_ currentText: NSAttributedString) -> NSMutableData {

    let pdfData = NSMutableData()

    // Create the PDF context using the default page size of 612 x 792.
    UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)

    let framesetter = CTFramesetterCreateWithAttributedString(currentText)

    var currentRange = CFRangeMake(0, 0);
    var currentPage = 0;
    var done = false;

    repeat {
        // Mark the beginning of a new page.
        UIGraphicsBeginPDFPageWithInfo(CGRect(x: 0, y: 0, width: 612, height: 792), nil);

        // Draw a page number at the bottom of each page.
        currentPage += 1;

        // Render the current page and update the current range to
        // point to the beginning of the next page.
        renderPagewithTextRange(currentRange: &currentRange, framesetter: framesetter)

        // If we're at the end of the text, exit the loop.
        if (currentRange.location == CFAttributedStringGetLength(currentText)){
            done = true;
        }
    } while (!done);

    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
    return pdfData
}

func renderPagewithTextRange (currentRange: inout CFRange,  framesetter: CTFramesetter) {
    // Get the graphics context.
    if let currentContext = UIGraphicsGetCurrentContext(){

        // Put the text matrix into a known state. This ensures
        // that no old scaling factors are left in place.
        currentContext.textMatrix = CGAffineTransform.identity;

        // Create a path object to enclose the text. Use 72 point
        // margins all around the text.
        let frameRect = CGRect(x: 72, y: 72, width: 468, height: 648);
        let framePath = CGMutablePath();
        framePath.addRect(frameRect)

        // Get the frame that will do the rendering.
        // The currentRange variable specifies only the starting point. The framesetter
        // lays out as much text as will fit into the frame.
        let frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, nil);

        // Core Text draws from the bottom-left corner up, so flip
        // the current transform prior to drawing.
        currentContext.translateBy(x: 0, y: 792);
        currentContext.scaleBy(x: 1.0, y: -1.0);

        // Draw the frame.
        CTFrameDraw(frameRef, currentContext);

        // Update the current range based on what was drawn.
        currentRange = CTFrameGetVisibleStringRange(frameRef);
        currentRange.location += currentRange.length;
        currentRange.length = 0;
    }
}

【讨论】:

  • 唯一的问题是由于某种原因不支持 NSAttributedString 中的 NSTextAttachment 图像
猜你喜欢
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多