Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDFKit Swapping Content of Annotation

Can the text (i.e. contents) of a FreeText annotation be changed in PDFKit without deleting an annotation / building a new annotation?

The following snippet does not change an annotation's contents when viewing in a PDFView:

let url = Bundle.main.url(forResource: "Test", withExtension: "pdf")!
let document = PDFDocument(url: url)!

for index in 0..<document.pageCount {
    let page: PDFPage = document.page(at: index)!
    let annotations = page.annotations
    for annotation in annotations {
        annotation.contents = "[REPLACED]"
    }
}
mainPDFView.document = document

This works - but requires replacing an annotation (and thus having to copy over all the other details of the annotation):

let url = Bundle.main.url(forResource: "Test", withExtension: "pdf")!
let document = PDFDocument(url: url)!

for index in 0..<document.pageCount {
    let page: PDFPage = document.page(at: index)!
    let annotations = page.annotations
    for annotation in annotations {
        print(annotation)
        page.removeAnnotation(annotation)
        let replacement = PDFAnnotation(bounds: annotation.bounds,
                                        forType: .freeText,
                                        withProperties: nil)

        replacement.contents = "[REPLACED]"
        page.addAnnotation(replacement)
    }
}

mainPDFView.document = document

Note: adding / removing the same annotation also does not help.

like image 290
Kevin Sylvestre Avatar asked Jul 23 '18 23:07

Kevin Sylvestre


1 Answers

I suggest you iterate over the annotations array using a classic for loop and find the index of the annotation you want to modify, after that subscripting the array should modify the annotation "in place".

Here's an example which modifies all annotations:

let url = Bundle.main.url(forResource: "Test", withExtension: "pdf")!
let document = PDFDocument(url: url)!

for index1 in 0..<document.pageCount {
    let page: PDFPage = document.page(at: index)!
    let annotations = page.annotations
    for index2 in 0..<annotations.count {
        annotations[index2].contents = "[REPLACED]"
    }
}

Have a read about mutating arrays: http://kelan.io/2016/mutating-arrays-of-structs-in-swift/

Hope it helps, cheers!

LE: It's a bug actually, see this one: iOS 11 PDFKit not updating annotation position

Maybe Apple will find a way to update the PDFView on screen when you change the contents of an annotation SOON..

like image 153
Mihai Erős Avatar answered Oct 22 '22 23:10

Mihai Erős