I just want to draw on a PDF file using PDFKit. This sounds simple but I'm having a lot of trouble. From the documentation, the ink annotations seem to be appropriate for this. Here's my code:
/// Adds a new annotation
func addAnnotation(color: UIColor, point: CGPoint) {
currentPage = pdfView.page(for: point, nearest: false)
// Here I convert the coordinates to the document and create a new annotation
if currentPage != nil {
let topRight = pdfView.convert(pdfView.frame.topRightCorner, to: currentPage!)
newAnnotation = PDFAnnotation(bounds: CGRect(origin: .zero, size: CGSize(width: topRight.x, height: topRight.y)), forType: .ink, withProperties: nil)
newAnnotation!.color = color
currentPage!.addAnnotation(newAnnotation!)
}
else {
newAnnotation = PDFAnnotation()
}
}
/// Adds a new path, maybe a new annotation
func addPath(color: UIColor, point: CGPoint, lineWidth: CGFloat) {
// Create annotation
if newAnnotation == nil {
addAnnotation(color: color, point: point)
}
guard currentPage != nil else { return }
let convertedPoint = pdfView.convert(point, to: currentPage!)
// Create initial path
let path = UIBezierPath()
path.lineWidth = 200
path.move(to: convertedPoint)
path.addLine(to: convertedPoint)
newAnnotation!.add(path)
}
/// Updates the last drawn annotation
func updatePath(point: CGPoint) {
if let annotation = newAnnotation, let page = currentPage {
let convertedPoint = pdfView.convert(point, to: page)
let lastPath = annotation.paths!.last!
lastPath.addLine(to: convertedPoint)
annotation.remove(lastPath)
annotation.add(lastPath)
}
}
My main problem is performance. I wrote all this code just to have a functional drawing program. What I understood in the process:
- Grouping the paths in the annotations instead of having one annotation per path seems to be more efficient. So I added the addAnnotation() method, which sometimes creates a new annotation.
- The 'bounds' property when creating an annotation plays a big part in performance. Setting this property to the page's bounds makes the program very slow.But the thing is, I don't know the bounds of the annotation before the user finish drawing...
I have a method touchMoved(), where I want to add a point the path. At first, I was just doing:
if let annotation = newAnnotation, let page = currentPage { let convertedPoint = pdfView.convert(point, to: page) let lastPath = annotation.paths!.last! lastPath.addLine(to: convertedPoint) }
but the path was not updating, so I added the lines:
annotation.remove(lastPath)
annotation.add(lastPath)
This turned out to be really bad in term of performances (the path sometimes disappear, and reappear later).
I'm assuming there's a better way to do all of this, but I can't find any good example. If you have a working example of Ink annotations on PDFKit, that would be also great.
Side question: in my code I set the bezierPath's lineWidth to 200. This is because I want to change the lineWidth of the annotation, but changing the bezierPath's lineWidth doesn't seem to change anything. Any idea on that ?