guco
guco

Reputation: 91

PdfKit highlight annotation

I'm trying to add highlight annotations to documents using PDFKit on iOS.

let highlight = PDFAnnotation(bounds: selection.bounds(for: page),
                              forType: PDFAnnotationSubtype.highlight,
                              withProperties: nil)

highlight.color = color

page.addAnnotation(highlight)
page.displaysAnnotations = true

When adding them using the code above, they appear as two differently shaped layers. When saving them to the PDF file and reopening it they display correctly.

In this screen capture

enter image description here

The top and bottom highlights have been added the same way using the snippet provided here. The top one has been saved to the pdf document and appears as expected when reopening it, the bottom one has just been added.

Does anyone know how to have them display correctly (i.e. like the top one) without resorting to saving and reopening the file?

Upvotes: 9

Views: 4451

Answers (2)

npalatov
npalatov

Reputation: 21

I've ended up with this hack method which takes into consideration all cases in my opinion. Hope that will help.

private func hackScroll(to page: PDFPage) {

    switch (pdfView.canGoToFirstPage(), pdfView.canGoToLastPage()) {
    case (true, false):
        pdfView.goToFirstPage(nil)
        pdfView.go(to: page)
    case (false, true):
        pdfView.goToLastPage(nil)
        pdfView.go(to: page)
    case (false, false):
        guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
        let file = "temp.pdf"

        /// Save to temp file
        let fileURL = dir.appendingPathComponent(file)
        pdfView.document?.write(to: fileURL)

        /// Read from temp file
        guard let document = PDFDocument(url: fileURL) else { return }
        pdfView.document = document
        pdfView.autoScales = true
    default:
        pdfView.goToFirstPage(nil)
        pdfView.go(to: page)
    }
}

Upvotes: 2

Johan de Klerk
Johan de Klerk

Reputation: 2535

So this is a know bug in 10.13. There is a workaround by scrolling the page away and then back to the highlight

You can create the highlight using this code:

let page = self.pdfDocument?.page(at: 10)
let bounds = CGRect(x: 85.8660965, y: 786.8891167, width: 298.41, height: 12.1485)
let annotation = PDFAnnotation(bounds: bounds, forType: .highlight, withProperties: nil)
annotation.color = NSColor.blue
page?.addAnnotation(annotation)

Then you need to scroll away from the page and back to the highlight

func annotationScrollHack(page: PDFPage) {
    guard let pdfDocument = self.pdfDocument else { return }

    //When adding highlights to macOS 10.13 it seems like 2 highlights are added.
    //If you scroll to a different page and back the "extra" highlight is removed
    //This function scrolls to the first/last page in the book and then back to the current page
    //rdar://34784917
    let bookScrollView = self.pdfView.documentView?.enclosingScrollView
    let currentVisibleRect = bookScrollView?.contentView.documentVisibleRect
    if (0 ... 3).contains(pdfDocument.index(for: page)) {
        if self.pdfView.canGoToLastPage {
            self.pdfView.goToLastPage(self)
        }
    } else {
        if self.pdfView.canGoToFirstPage {
            self.pdfView.goToFirstPage(self)
        }
    }

    if let currentVisibleRect = currentVisibleRect {
        bookScrollView?.contentView.scroll(to: CGPoint(x: currentVisibleRect.origin.x, y: currentVisibleRect.origin.y))
    }
}

Response from Apple:

There is no workaround other than the “hack" they described: scrolling away then back is the best option. Changing zoom factor and reverting it might fix it in the same way, but not guaranteed.

Upvotes: 2

Related Questions