Apple Pencil


PSPDFKit 6.5 for iOS adds first-class support for Apple Pencil. There are a few places where you can customize how Apple Pencil interacts with PSPDFKit:

Default behavior

The default flow of using Apple Pencil with PSPDFKit is:

Users can select an annotation tool from PSPDFAnnotationToolbar. Whenever a touch from Apple Pencil is detected, the global PSPDFStylusManager makes PSPDFApplePencilDriver its current driver. This can be disabled by setting automaticallyEnablesApplePencil to NO.

PSPDFAnnotationStateManager decides whether to allow direct (finger) touches to create annotations depending on if PSPDFApplePencilDriver is the current driver. This means after the user starts annotating with Apple Pencil, direct touches stop creating annotations so the user can scroll and tap with fingers as normal. This can be changed by setting the stylusMode property.

After detecting a touch from Apple Pencil the first time, PSPDFAnnotationToolbar shows a stylus button that shows the stylus connection status. This can be disabled by setting showsStylusButtonAutomatically to NO. When this button is tapped, the PSPDFKit.sharedInstance.stylusManager.stylusController is shown which allows the user to stop using Apple Pencil if they prefer to annotate using fingers.

Apple Pencil availability

There is no simple way to know whether a device supports Apple Pencil, whether the user has one, and if it is currently connected. All an app knows is that if it receives a touch event of type UITouchTypeStylus then an Apple Pencil was connected at that time.

PSPDFKit models the availability of Apple Pencil with the detected class property on PSPDFApplePencilDriver. PSPDFKit sets this to YES whenever detecting a touch of type UITouchTypeStylus on a page view. If your app detect a touch from Apple Pencil elsewhere, you can set this property so PSPDFKit can show the stylus button in the annotation toolbar as soon as it appears:

Copy
1
2
3
4
let touch: UITouch = ...
if touch.type == .stylus {
    PSPDFApplePencilDriver.wasDetected = true
}
Copy
1
2
3
4
UITouch *touch = ...
if (touch.type == UITouchTypeStylus) {
    PSPDFApplePencilDriver.detected = YES;
}

Every time this property is set, the PSPDFApplePencilDriver class posts PSPDFApplePencilDetectedNotification. Note that this happens even if the value does not change which, for example, allows PSPDFStylusManager to reenable Apple Pencil each time a touch from one is detected.

To only show a UI element if Apple Pencil is definitely available so it does not clutter the screen otherwise:

Copy
1
2
3
4
5
6
7
func someSetupMethod() {
    NotificationCenter.default.addObserver(self, selector: #selector(stylusDetectionChanged(notification:)), name: .PSPDFApplePencilDetected, object: PSPDFApplePencilDriver.self)
}

@objc func stylusDetectionChanged(notification: Notification) {
    self.showsSomeStylusUI = PSPDFApplePencilDriver.wasDetected;
}
Copy
1
2
3
4
5
6
7
- (void)someSetupMethod {
    [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(stylusDetectionChanged:) name:PSPDFApplePencilDetectedNotification object:PSPDFApplePencilDriver.class];
}

- (void)stylusDetectionChanged:(NSNotification *)notification {
   self.showsSomeStylusUI = PSPDFApplePencilDriver.wasDetected;
}

Always create a particular annotation type with Apple Pencil

You can make touches with Apple Pencil always create that annotation, which would be a good fit if your app does not show the annotation toolbar and focuses on one type of annotation. For example, so Pencil touches always draw ink — or always highlights text similar to iBooks, which you can see in the iBooks-like highlighting example (PSCiBooksHighlightingExample).

First set up the annotation state manager:

Copy
1
2
3
let annotationStateManager = pdfController.annotationStateManager
annotationStateManager.state = .ink
annotationStateManager.stylusMode = .stylus
Copy
1
2
3
PSPDFAnnotationStateManager *annotationStateManager = pdfController.annotationStateManager;
annotationStateManager.state = PSPDFAnnotationStringInk;
annotationStateManager.stylusMode = PSPDFAnnotationStateManagerStylusModeStylus;

Make sure the user can’t change the state by disabling the annotation toolbar by removing the annotationButtonItem which is included by default, and disabling the menu shown on long press:

Copy
1
2
3
4
pdfController.navigationItem.setRightBarButtonItems([pdfController.thumbnailsButtonItem, pdfController.activityButtonItem /* etc. as long as this excludes annotationButtonItem */], for: .document, animated: false)
pdfController.updateConfiguration { builder in
    builder.isCreateAnnotationMenuEnabled = false
}
Copy
1
2
3
4
[pdfController.navigationItem setRightBarButtonItems:@[pdfController.thumbnailsButtonItem, pdfController.activityButtonItem /* etc. as long as this excludes annotationButtonItem */] forViewMode:PSPDFViewModeDocument animated:NO];
[pdfController updateConfigurationWithBuilder:^(PSPDFConfigurationBuilder *builder) {
    builder.createAnnotationMenuEnabled = NO;
}];
Was this page helpful? We're happy to answer any questions.