【问题标题】:Swift iOS - Overlay text onto PDF with PDFKit and UISwift iOS - 使用 PDFKit 和 UI 将文本叠加到 PDF 上
【发布时间】:2021-01-30 05:41:37
【问题描述】:

我在 Swift 5 和 iOS 上工作。我正在尝试将文本覆盖到我拥有的当前 PDF 上。我实际上是在移植我从 macOS 应用程序中制作的代码。这是Mac版的代码:

func executeContext(at srcURL: URL, to dstURL: URL) {
    
    // Confirm there is a document there
    if let doc: PDFDocument = PDFDocument(url: srcURL) {
        
        // Create a document, get the first page, and set the size of the page
        let page: PDFPage = doc.page(at: 0)!
        var mediaBox: CGRect = CGRect(x: 0, y: 0, width: 792, height: 612)
        
        // This is where the magic happens.  Create the drawing context on the PDF
        let context = CGContext(dstURL as CFURL, mediaBox: &mediaBox, nil)
        let graphicsContext = NSGraphicsContext(cgContext: context!, flipped: false)
        NSGraphicsContext.current = graphicsContext
        
        context!.beginPDFPage(nil)
        
        // Draws the PDF into the context
        page.draw(with: .mediaBox, to: context!)
        
        // Parse and Draw Text on the context
        //drawText()
        
        let attributes = [
            NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 72)
        ]
        let text = "I'm a PDF!"
        text.draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
        
        context!.saveGState()
        
        context!.restoreGState()
        
        context!.endPDFPage()
        NSGraphicsContext.current = nil
        context?.closePDF()
    }
}

drawText() 函数完成了大部分需要的文本覆盖,但我在它下面放置了另一个“绘制”方法来测试它。

我得到一个错误Cannot find 'NSGraphicsContext' in scope 是可以理解的,因为 NSGraphicsContext 在 iOS 上不存在。我尝试使用 UIGraphicsPDFRenderer 或 UIGraphicsBeginPDFContextToData 找到等效的翻译,并使用 Ray Wenderlich tutorial 中的一些代码,我能够创建一个新的 PDF 并使用以下代码在其上放置文本:

func createDocument(url: URL) -> Data {
    
    //let pdfData = try? Data.init(contentsOf: url)
    
    // 1
    let pdfMetaData = [
        kCGPDFContextCreator: "Timecard App",
        kCGPDFContextAuthor: "Timecard App"
    ]
    let format = UIGraphicsPDFRendererFormat()
    format.documentInfo = pdfMetaData as [String: Any]
    
    // 2
    let pageWidth = 8.5 * 72.0
    let pageHeight = 11 * 72.0
    let pageRect = CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)
    
    // 3
    let renderer = UIGraphicsPDFRenderer(bounds: pageRect, format: format)
    
    // 4
    let data = renderer.pdfData { (context) in
        // 5
        context.beginPage()
        // 6
        let attributes = [
            NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 72)
        ]
        let text = "I'm a PDF!"
        text.draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
    }
    
    return data
}

...但是我找不到将当前 PDF“数据”加载到渲染器然后从那里绘制的方法。有没有人对正确的方法有任何建议?

【问题讨论】:

    标签: ios swift swift5 pdfkit uigraphicscontext


    【解决方案1】:

    这是可能的解决方案 - 实际上您只需要直接使用 CoreGraphics 上下文进行操作,设置当前、翻转变换等(保留原始代码的样式和约定)。

    使用 Xcode 12 / iOS 14 测试。

    func executeContext(at srcURL: URL, to dstURL: URL) {
        
        // Confirm there is a document there
        if let doc: PDFDocument = PDFDocument(url: srcURL) {
            
            // Create a document, get the first page, and set the size of the page
            let page: PDFPage = doc.page(at: 0)!
            var mediaBox: CGRect = page.bounds(for: .mediaBox)
        
            // This is where the magic happens.  Create the drawing context on the PDF
            let context = CGContext(dstURL as CFURL, mediaBox: &mediaBox, nil)
    
            UIGraphicsPushContext(context!)
            context!.beginPDFPage(nil)
    
            // Draws the PDF into the context
            page.draw(with: .mediaBox, to: context!)
            
            let flipVertical: CGAffineTransform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: mediaBox.size.height)
            context!.concatenate(flipVertical)
    
            let attributes = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 72)
            ]
            let text = "I'm a PDF!"
            text.draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
            
            context!.endPDFPage()
            context?.closePDF()
    
            UIGraphicsPopContext()
        }
    }
    

    【讨论】:

    • 非常感谢!我只需要更改媒体框线即可使用我的特定 pdf。
    • @Asperi 这对我很有用。我有一个要编辑的多页 PDF。我将如何去添加额外的页面?当我尝试添加第二页时,它会覆盖第一页。
    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    相关资源
    最近更新 更多