Reputation: 126
Here is what I am doing currently.
First, I get the document. Next I create a PDF View and assign the document to the view. Then I create a view and do my drawing in the view, then add the view to the PDFView as a subview. Then I convert the PDFView to data, then to PDF document. Since I'm doing the drawing on the first page of the PDF, I remove the first page from the original PDF, insert the new first page, and return the document.
guard let document = PDFDocument(url: url) else { return nil }
guard let page = document.page(at: 0) else { return nil }
let pageBounds = page.bounds(for: .mediaBox)
let pdfView = PDFView(frame: pageBounds)
pdfView.document = document
pdfView.enclosingScrollView?.autohidesScrollers = true
let view = /// code for subview that I am drawing on
pdfView.addSubview(view)
let data = pdfView.dataWithPDF(inside: pageBounds)
guard let pdf = PDFDocument(data: data) else { return nil }
document.removePage(at: 0)
document.insert(pdf.page(at: 0)!, at: 0)
return document
Is there a better way to do this? To add a wrinkle, my final product has a weird scroll bar image (see Screenshot). I tried adding auto hide scrollers & enclosingScrollView?.hasVerticalScroller = false but neither seem to hide the scroll bar.
Thanks in advance!
Upvotes: 1
Views: 3247
Reputation: 535191
A simple solution is demonstrated in the 2017 WWDC video on PDFKit. I assume you have an existing document to which you want to add some drawing. Here's what to do:
Give the document a delegate.
In the delegate, implement classForPage
to declare a class for your pages: that class should be your own PDFPage subclass.
In your PDFPage subclass, implement draw(with:to:)
. You are given a context; draw into it! Be sure to call super
if you want the default drawing to happen.
If your PDFPage subclass needs to draw different things on different pages, it can find out where it is in the document by asking for self.document?.index(for:self)
.
Upvotes: 2
Reputation: 126
So I've solved my own problem. For anyone else stuck like me, here is what I did. For example to draw a box on a page:
and:
ctx?.beginPDFPage(nil)
ctx?.drawPDFPage(cgPage)
ctx?.beginPath()
let path = CGPath(roundedRect: box as CGRect, cornerWidth: 5, cornerHeight: 5, transform: nil)
ctx?.setStrokeColor(CGColor.black)
ctx?.setFillColor(color.cgColor)
ctx?.setLineWidth(10.0)
ctx?.addPath(path)
ctx?.strokePath()
ctx?.addPath(path)
ctx?.fillPath()
ctx?.endPDFPage()
ctx?.closePDF()
(If you created the context with a URL, close will write to disk. Otherwise you'll have to do something with the PDF data.)
Upvotes: 1