2017-06-13 92 views
0

我有一個相當長的NSAttributedString,我試圖提請PDF,使得單頁PDF與平局FUNC很簡單:生成多頁PDF SWIFT 3

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/ 但我無法弄清楚得到它在斯威夫特似乎也蘋果官方文檔只用於OBJ-C https://developer.apple.com/library/content/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GeneratingPDF/GeneratingPDF.html

+0

我最近不得不做同樣的事情 - 我有一個多節打印表,它可能會拆分多個頁面。我的解決方案是每次添加一行到UIWebView,並使用'webViewDidFinishLoad'來檢查頁面大小 - 一旦它超出了我使用以前的html文本的頁面,並創建一個新的UIWebView。完成所有網頁後,創建多頁PDF是一項簡單的任務 – Russell

回答

0

我終於成功地轉換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; 
    } 
}