NEW: Learn SwiftUI with my free YouTube video series! >>

How to watermark PDFs inside a PDFView

Swift version: 5.0

Paul Hudson    @twostraws   

PDFKit makes it easy to watermark PDFs as they are rendered, for example to add “FREE SAMPLE” over pages. It takes six steps, five of which are trivial and one which involves a little Core Graphics heavy lifting.

Let’s get the easy stuff out of the way:

  1. Create a new Cocoa Touch Class called “SampleWatermark”, making it a subclass of PDFPage.
  2. Add import PDFKit to the top of the new file.
  3. Open whichever view controller owns your PDFView and make the ViewController class conform to the PDFDocumentDelegate protocol.
  4. Find the code where you load your document (something like pdfView.document = document) then insert this directly before: document.delegate = self. That means the document will ask your view controller what class it should use to render pages.
  5. Finally, we need to add a new method to the view controller to tell it to use the SampleWatermark class for its pages.

Add this method to your view controller now:

func classForPage() -> AnyClass {
    return SampleWatermark.self

What we’ve just done is create a new PDFPage subclass that will handle watermark rendering, then tell our PDFDocument to use it for all pages. We haven’t given the SampleWatermark class any code yet, which means it will look just like a regular page – we’re going to fix that now.

When doing custom PDF rendering there are a few things to know:

  1. If you draw your content before calling super.draw(), your content will appear behind the page content. That might be what you want, but we’ll be doing the opposite here.
  2. You’re given a graphics context to draw into, but you should tread carefully: save the context and its state before you make any changes, then restore them afterwards.
  3. PDFs have a variety of drawing boxes that determine how things are displayed. We don’t care which one is used, but we do need to ask PDFKit to tell us the page bounds for that box so we know how to position our text.
  4. UIKit and PDFs draw in different directions, but you can correct that by moving the drawing position down by the height of the document then flipping its Y axis.

We’re going to write the words “FREE SAMPLE” in red, centered near the top of each page using a bold font. Add this method to SampleWatermark.swift:

override func draw(with box: PDFDisplayBox, to context: CGContext) {
    super.draw(with: box, to: context)

    let string: NSString = "FREE SAMPLE"
    let attributes: [NSAttributedString.Key: Any] = [.foregroundColor:, .font: UIFont.boldSystemFont(ofSize: 32)]
    let stringSize = string.size(withAttributes: attributes)


    let pageBounds = bounds(for: box)
    context.translateBy(x: (pageBounds.size.width - stringSize.width) / 2, y: pageBounds.size.height)
    context.scaleBy(x: 1.0, y: -1.0)

    string.draw(at: CGPoint(x: 0, y: 55), withAttributes: attributes)


If everything went well you should now see “FREE SAMPLE” emblazoned across every page of your PDF.

SPONSOR Meet the new Instabug – more than just bug reporting! We help you build better apps and minimize your debugging time. With each bug report, we automatically capture details like network requests, repro steps, and session details. Get real-time crash reports with stack trace details and session data to help you catch and fix issues easily. And with our customizable in-app surveys, you’ll gather insightful user feedback and much more. Instabug is the fastest and easiest way to release with confidence. Start your free trial now! Start your free trial now!

Available from iOS – learn more in my book Advanced iOS: Volume Two

Did this solution work for you? Please pass it on!

Other people are reading…

About the Swift Knowledge Base

This is part of the Swift Knowledge Base, a free, searchable collection of solutions for common iOS questions.

Buy Testing Swift Buy Practical iOS 12 Buy Pro Swift Buy Swift Design Patterns Buy Swift Coding Challenges Buy Server-Side Swift (Vapor Edition) Buy Server-Side Swift (Kitura Edition) Buy Hacking with macOS Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with Swift Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let me know!

Average rating: 5.0/5

Click here to visit the Hacking with Swift store >>