Search code examples
iosswiftpdfkitpdfview

PDFView doesn't highlight search results


I'm trying out PDFView and want to highlight searched words. I was following this little tutorial right here (see search paragraph).

I am getting matches for my PDF but when I set pdfView.highlightedSelections = searchedItems nothing happens.

Here's my code (VC extends PDFDocumentDelegate)

var document: PDFDocument!
var searchedItems: [PDFSelection] = []


override func viewDidLoad() {
    super.viewDidLoad()

    let url = Bundle.main.url(forResource: "test3", withExtension: "pdf")
    document = PDFDocument(url: url!)
    pdfView.document = document
    pdfView.document?.delegate = self
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    pdfView.document?.findString("Product", withOptions: .caseInsensitive)
}

func documentDidEndDocumentFind(_ notification: Notification) {
    pdfView.highlightedSelections = nil
    pdfView.highlightedSelections = searchedItems
}

func documentDidFindMatch(_ notification: Notification) {
    if let selection = notification.userInfo?.first?.value as? PDFSelection {
        selection.color = .yellow
        searchedItems.append(selection)
        print("didFindMatch")
    }
}

Solution

  • Okay I figured it out for myself, by reading this thread here: https://forums.developer.apple.com/thread/93414

    It seems that highlightedSelections doesn't work as documented. I will file a bug at Apple.

    PDFSelection itself has an inner array of Type PDFSelection. With this I can add multiple selections inside one. After that I can use pdfView.setCurrentSelection(_:animate:) to set this nested selection array.

    var document: PDFDocument!
    var searchedItem: PDFSelection?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let url = Bundle.main.url(forResource: "test3", withExtension: "pdf")
        document = PDFDocument(url: url!)
        pdfView.document = document
        pdfView.document?.delegate = self
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
            self.document?.beginFindString("Product", withOptions: .caseInsensitive)        
    }
    
    func documentDidEndDocumentFind(_ notification: Notification) {
        pdfView.setCurrentSelection(searchedItem, animate: true)
    }
    
    func documentDidFindMatch(_ notification: Notification) {
        if let selection = notification.userInfo?.first?.value as? PDFSelection {
            selection.color = .yellow
            if searchedItem == nil {
                // The first found item sets the object.
                searchedItem = selection
            } else {
                // All other found selection will be nested
                searchedItem!.add(selection)
            }
        }
    }