Swift PDFKit draw multiple images in a single PDFPage

954 Views Asked by At

I'm trying to draw multiple images into a single PDFPage.
Looking at the docs and over StackOverflow seems like the best I got is to use PDFPage with an UIImage initializer like so:

let pdfPage = PDFPage(image: image)

But it just creates a page with a full-page image. I tried to draw the images using CGContext but I don't understand how to use PDFPage within a drawing context for it to draw the images rapidly like in the example below.

let bounds = page.bounds(for: .cropBox)

// Create a `UIGraphicsImageRenderer` to use for drawing an image.
let renderer = UIGraphicsImageRenderer(bounds: bounds, format: UIGraphicsImageRendererFormat.default())

let image = renderer.image { (context) in

 // How do I rapidly draw them here?

}

Any help will be highly appreciated!

The result I get with PDFPage(image: <UIImage>) vs expected result:

enter image description here

1

There are 1 best solutions below

3
LoVo On BEST ANSWER

You probably need to improve the positioning logic for the image in the loop, but this should point you to the right direction.

import UIKit
import PDFKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
              
        let pdfView = PDFView()
        pdfView.frame = CGRect(x: 0, y: 50, width: view.frame.width, height: view.frame.height - 50)
        if let d = createPDFDocument() {
            pdfView.document = d
        }
        
        view.addSubview(pdfView)
    }

    func createPDFDocument() -> PDFDocument? {
        let pdfDocument = PDFDocument()
        let page = PDFPage()
        let bounds = page.bounds(for: .cropBox)
        let imageRenderer = UIGraphicsImageRenderer(bounds: bounds, format: UIGraphicsImageRendererFormat.default())
        let image = imageRenderer.image { (context) in
            context.cgContext.saveGState()
            context.cgContext.translateBy(x: 0, y: bounds.height)
            context.cgContext.concatenate(CGAffineTransform.init(scaleX: 1, y: -1))
            page.draw(with: .mediaBox, to: context.cgContext)
            context.cgContext.restoreGState()

            // Improve logic for image position
            Range(1...4).forEach { value in
                let image = UIImage(named: "YOUR_IMAGE_NAME")
                let rect = CGRect(x: 50 * value, y: 0, width: 40, height: 100)
                image?.draw(in: rect)
            }
        }
        
        let newPage = PDFPage(image: image)!
        pdfDocument.insert(newPage, at: 0)

        return pdfDocument
    }
}