Introduction to Annotations

PSPDFKit supports all common annotation types:

These are standard annotations (as defined in the PDF Reference) that can be read and written by many apps, like Adobe Acrobat or even Apple’s Preview.app. Most of these annotation types can also be written back, with the exception of rich media/video, file, and widget. (See also: What Are Annotations?)

Working with Annotations in Code

You can work with all supported annotations not only in our UI but also in code. We have APIs for various operations, including getting, setting, modifying, and removing annotations.

To get all annotations on a certain document page, you can call annotationsForPageAtIndex:type:

1
2
// Get all annotations on the first page.
let annotations = document.annotationsForPage(at: 0, type: .all)
Copy
1
2
// Get all annotations on the first page.
NSArray<__kindof PSPDFAnnotation *> *annotations = [document annotationsForPageAtIndex:0 type:PSPDFAnnotationTypeAll]

Creating Annotations

You can instantiate annotations with their corresponding classes, which are all subclasses of the base PSPDFAnnotation class:

Copy
1
2
3
4
5
6
// Create a free text annotation.
let freeTextAnnotation = PSPDFFreeTextAnnotation()
freeTextAnnotation.contents = "This is a free text annotation."
freeTextAnnotation.fontSize = 20
freeTextAnnotation.boundingBox = CGRect(x: 200, y: 200, width: 200, height: 200)
freeTextAnnotation.pageIndex = 0
Copy
1
2
3
4
5
6
// Create a free text annotation.
PSPDFFreeTextAnnotation *freeTextAnnotation = [[PSPDFFreeTextAnnotation alloc] init];
freeTextAnnotation.contents = @"This is a free text annotation.";
freeTextAnnotation.fontSize = 20.f;
freeTextAnnotation.boundingBox = CGRectMake(200.f, 200.f, 200.f, 200.f);
freeTextAnnotation.pageIndex = 0;

For a more detailed guide, please refer to Programmatically Creating Annotations.

Adding and Removing Annotations

To add annotations on a document page, you can use addAnnotations:options: on PSPDFDocument. To remove annotations on the document, you can use removeAnnotations:options::

Copy
1
2
3
4
5
// Add an annotation to a document.
document.add([freeTextAnnotation])

// Remove an annotation from a document.
document.remove([freeTextAnnotation])
Copy
1
2
3
4
5
// Add an annotation to a document.
[document addAnnotations:@[freeTextAnnotation] options:nil];

// Remove an annotation from a document.
[document removeAnnotations:@[freeTextAnnotation] options:nil];

You can also remove all annotations from a document using allAnnotationsOfType: and removeAnnotations:options:. You usually don’t want to remove links and form elements, which are also annotations. These annotation types can be excluded, as seen in the code snippet below:

Copy
1
2
3
4
5
6
7
var annotationTypes = PSPDFAnnotationType.all
annotationTypes.remove([.link, .widget])
let allAnnotationsDictionary = document.allAnnotations(of: annotationTypes)
let allAnnotations = allAnnotationsDictionary.flatMap { key, value in
    return value
}
document.remove(allAnnotations)
Copy
1
2
3
4
5
6
7
NSDictionary *allAnnotationsDictionary = [document allAnnotationsOfType:PSPDFAnnotationTypeAll & ~(PSPDFAnnotationTypeLink|PSPDFAnnotationTypeWidget)];

NSMutableArray *allAnnotations = [NSMutableArray array];
[allAnnotationsDictionary enumerateKeysAndObjectsUsingBlock: ^(NSNumber *key, NSArray *value, BOOL *stop) {
    [allAnnotations addObjectsFromArray:value];
}];
[document removeAnnotations:allAnnotations options:nil];

Saving Annotations with PSPDFKit

ℹ️ Note: Annotations can only be written back into a PDF if the file is writeable. The default location (App Bundle) is read-only. Copy the PDF into your Documents folder (see the Test PDF Annotation Writing example in PSPDFCatalog).

Optionally, and as a fallback, annotations can also be written as external files. This is the default behavior if a PDF is read-only and can be customized by changing annotationSaveMode. The valid options are: PSPDFAnnotationSaveModeDisabled, PSPDFAnnotationSaveModeExternalFile, PSPDFAnnotationSaveModeEmbedded, and PSPDFAnnotationSaveModeEmbeddedWithExternalFileAsFallback (default).

For more information, please see the Annotation-Saving Mechanism guide.

Handling Annotations with PSPDFKit

Annotations are handled by the PSPDFAnnotationManager class, an instance of which is managed by a PSPDFDocumentProvider. A PSPDFDocument has one or more PSPDFDocumentProviders, depending on the amount of PDF files it contains (usually just one). The preferred way to customize annotation handling is to implement a custom PSPDFAnnotationProvider subclass. We provide a PSPDFContainerAnnotationProvider subclass that is a good base to build upon. If you want to change PSPDFAnnotationManager across the application, the best way to do this is to use overrideClass:withClass: on PSPDFDocument.

Make sure to add the annotationButtonItem to the toolbar to be able to show the annotation toolbar. With PSPDFConfiguration’s editableAnnotationTypes property, you can customize which annotations can be edited. Set this to an empty array to disable annotation editing.

Checking If a Document Contains Annotations

When calling allAnnotationsOfType:, PSPDFKit will return all annotations of the specified type(s). To check if a document contains annotations, you will likely want to use PSPDFAnnotationTypeAll & ~(PSPDFAnnotationTypeLink|PSPDFAnnotationTypeWidget), like so:

Copy
1
2
3
var annotationTypes = PSPDFAnnotationType.all
annotationTypes.remove([.link, .widget])
let allAnnotationsDictionary = document.allAnnotations(of: annotationTypes)
Copy
1
NSDictionary *allAnnotationsDictionary = [document allAnnotationsOfType:PSPDFAnnotationTypeAll & ~(PSPDFAnnotationTypeLink|PSPDFAnnotationTypeWidget)];

This returns all annotations, excluding link and widget annotations. Widget annotations include simple buttons and all form element types. allAnnotationsOfType: returns a dictionary where the key is the page number and the value is an array containing all annotations on that page, so you need to check if any of those arrays have any annotations.

PSPDFCatalog contains many examples of working with annotations, so be sure to check them out.

Uniquely Identifying Annotations

While the name property of an annotation is defined in the PDF spec as optional, PSPDFKit automatically sets name to a unique identifier (UUID) each time an annotation is created.

Storing Custom Data in Annotations

You can persistently store custom data on a per-annotation basis using PSPDFAnnotation’s customData property. More information about customData is available in the corresponding guide.