I achieved this by creating the following extension:
extension PDFDocument {
func unifiedPDFPageWidth(targetWidth: CGFloat = 595) -> PDFDocument {
let newPDF = PDFDocument() // Create a new PDF document with normalized page widths
for index in 0 ..< pageCount {
guard let page = page(at: index) else { continue }
let origBounds = page.bounds(for: .mediaBox) // Get the full page bounds
let originalWidth = origBounds.width
// If the page already has the target width, insert it unchanged
if originalWidth == targetWidth {
newPDF.insert(page, at: index)
continue
}
// Compute the scaling factor and new page size
let scale = targetWidth / originalWidth
let newSize = CGSize(width: targetWidth, height: origBounds.height * scale)
// Render the page into a new PDF context
let renderer = UIGraphicsPDFRenderer(bounds: CGRect(origin: .zero, size: newSize))
let pageData = renderer.pdfData { context in
context.beginPage(withBounds: CGRect(origin: .zero, size: newSize), pageInfo: [:])
let cgContext = context.cgContext
cgContext.saveGState() // Save the current graphics state
// Adjust coordinate system and apply scaling
cgContext.translateBy(x: 0, y: newSize.height) // Shift origin to the top-left
cgContext.scaleBy(x: scale, y: -scale) // Scale while flipping vertically
page.draw(with: .mediaBox, to: cgContext) // Draw the page content
cgContext.restoreGState() // Restore the original state
}
// Convert the rendered page data into a PDFPage and insert it
if let newPage = PDFDocument(data: pageData)?.page(at: 0) {
newPDF.insert(newPage, at: index)
}
}
return newPDF // Return the final normalized PDF document
}
}