1

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

Roi Mulia
  • 5,626
  • 11
  • 54
  • 105
  • Check [this tutorial](https://www.kodeco.com/4023941-creating-a-pdf-in-swift-with-pdfkit). The Adding Images part explains how to add images with passed size. – LoVo Nov 03 '22 at 08:25
  • Hey @LoVo, thanks! I checked it but he is not using PDFPage, he createss a direct context and creates the page from there. – Roi Mulia Nov 03 '22 at 11:02

1 Answers1

1

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
    }
}
LoVo
  • 1,856
  • 19
  • 21
  • Hey LoVo, thanks for the help! This seems to work overall. Can you tell me why you added 50 points margin at the top? – Roi Mulia Nov 03 '22 at 15:23
  • pdfView.frame = CGRect(x: 0, y: 50, width: view.frame.width, height: view.frame.height - 50) – Roi Mulia Nov 03 '22 at 15:23
  • I just had the feeling the notch was covering a bit of my image but that doesn't have an impact on the pdf. It just the position of the PDFView. – LoVo Nov 04 '22 at 08:33