iosswiftpdfapple-pdfkit

Add a footer like "page x of y" when creating a PDF using UIGraphicsPDFRenderer


I'm working on a function in my app that lets users export their data into a nicely designed PDF.

I'm using UIGraphicsPDFRenderer for this and I went through Apple's documentation.

I'm having a problem adding a footer like "page x of y". While "x" is easy - I'm having troubles determining the "y" since I only know how many pages my document has once I have fully rendered the PDF. I cannot determine the number of pages in advance because of the rather complex layout.

Now I also know that new pages are created with beginPage(). Is there also a way to go to the previous page? - Because then I could simply go through the document and add the missing footer.

Here's the code I use (very much simplified, but it should be enough to get the idea) in Swift 4:

let pdf = renderer.pdfData { (context) in
  let attributes = [ NSFontAttributeName : UIFont.boldSystemFont(ofSize: 15) ]
  // page 1
  context.beginPage()
  NSAttributedString(string: "Page 1", attributes: attributes).draw(in: CGRect(x: 0, y: 0, width: 500, height: 200))

  // page 2
  context.beginPage()
  NSAttributedString(string: "Page 2", attributes: attributes).draw(in: CGRect(x: 0, y: 0, width: 500, height: 200))

  // page 3
  context.beginPage()
  NSAttributedString(string: "Page 3", attributes: attributes).draw(in: CGRect(x: 0, y: 0, width: 500, height: 200))

  // Now that I know that the PDF will have 3 pages, add the footer on all 3 pages - but how?
  }
}

Solution

  • UIGraphicsPDFRenderer is a forward only pdf generator.
    You have 2 options:

    1. (recommended) Analyze the data before writing it to pdf to determine on how many pages it fits. Since your code performs the page breaks you should be able to compute how many pages are required for your data.
    2. Create your document without ‘page x of y’ and save it. Create a new document, open the previously saved document and draw its pages on the pages of the new document and then add the ‘page x of y’.

    2 is more cumbersome and inefficient so I would go with 1. Because saving, editing and deleting takes more CPU and memory.