Apple Pencil Double Tap
A Flutter plugin for Apple Pencil double-tap and squeeze gestures on compatible iPads, with iOS integration that also allows iPhone Duo. Gesture availability depends on the Apple Pencil model.
Receive native UIKit Apple Pencil interactions through Dart callbacks in your Flutter iOS app.
Features
- Detect Apple Pencil double-tap gestures (Apple Pencil 2nd generation or Apple Pencil Pro)
- Detect Apple Pencil squeeze gestures (Apple Pencil Pro only)
- Gesture callbacks with hover pose information when available
- Access user's preferred action settings from iOS Settings app
- Native UIKit registration on iPad and iPhone, including iPhone Duo
- Swift Package Manager support
Device and Apple Pencil compatibility
| Device and Apple Pencil | Double-tap | Squeeze |
|---|---|---|
| Compatible iPad + Apple Pencil (2nd generation) | Yes | No |
| Compatible iPad + Apple Pencil Pro | Yes | Yes, with iPadOS 17.5+ |
| iPhone Duo + Apple Pencil (USB-C) | No | No |
| Apple Pencil (1st generation) or Apple Pencil (USB-C) | No | No |
The plugin no longer restricts UIPencilInteraction registration to the iPad device idiom. It can be included in iPhone Duo apps, but this does not add double-tap or squeeze to Apple Pencil (USB-C). Apple's iPhone Duo announcement lists Apple Pencil (USB-C) support as coming later in 2026; that model has neither gesture. See Apple's Pencil feature comparison for hardware capabilities.
This package listens for UIKit gesture callbacks. It does not implement drawing, handwriting recognition, raw stylus input, or standalone hover tracking. No gesture callbacks are expected on hardware without double-tap or squeeze. iPhone Duo hardware has not been tested with this release.
Requirements
- iOS/iPadOS 15.0 or later
- Apple Pencil (2nd generation) for double-tap
- Apple Pencil Pro for squeeze gesture (requires iPadOS 17.5+)
- Dart 3.13.0 or later
- Flutter 3.47.0 or later
- Xcode 15.4 or later for the iOS 17.5 Pencil APIs; your Flutter version may require a newer Xcode
Installation
In the dependencies: section of your pubspec.yaml, add the following line:
apple_pencil_double_tap: ^2.0.0
Then run:
flutter pub get
Swift Package Manager
This plugin supports both CocoaPods and Swift Package Manager for iOS integration.
Swift Package Manager is enabled by default in current Flutter releases. If your local configuration has disabled it, enable it with:
flutter config --enable-swift-package-manager
Usage
Basic Setup
import 'package:apple_pencil_double_tap/apple_pencil_double_tap.dart';
final applePencil = ApplePencilDoubleTap();
applePencil.listen(
// Before iPadOS 17.5 (legacy API)
v1Callback: (PreferredAction preferredAction) {
print('Double tap detected. Preferred user action: $preferredAction');
},
// For iPadOS >=17.5 (new API with hover pose)
onTapAction: (TapAction action) {
print('TapAction: $action');
print('Preferred action: ${action.preferredAction}');
if (action.zOffset != null) {
print('Hover z-offset: ${action.zOffset}');
}
},
// For iPadOS >=17.5 - Apple Pencil Pro squeeze gesture
onSqueeze: (SqueezeAction action) {
print('SqueezeAction: $action');
print('Phase: ${action.squeezePhase}');
print('Preferred action: ${action.preferredAction}');
},
onError: (e) {
print('Error: $e');
},
);
// Call from your widget's dispose method when done
applePencil.dispose();
Handling Squeeze Events
The squeeze gesture is a continuous interaction available only on Apple Pencil Pro. It provides phase information to track the gesture lifecycle:
applePencil.listen(
onSqueeze: (SqueezeAction action) {
switch (action.squeezePhase) {
case SqueezePhase.began:
print('Squeeze started');
break;
case SqueezePhase.changed:
print('Squeeze ongoing');
break;
case SqueezePhase.ended:
print('Squeeze completed - perform action');
break;
case SqueezePhase.cancelled:
print('Squeeze was cancelled');
break;
case SqueezePhase.unknown:
print('Unknown phase');
break;
}
},
);
API Reference
ApplePencilDoubleTap
The main class for interacting with Apple Pencil.
Methods
listen({...})- Start listening for Apple Pencil interactionsdispose()- Stop listening and clean up resources
Callback Parameters
| Parameter | Type | Description |
|---|---|---|
v1Callback |
Function(PreferredAction)? |
Legacy callback for iPadOS <17.5 |
onTapAction |
Function(TapAction)? |
Callback for double-tap events (iPadOS 17.5+) |
onSqueeze |
Function(SqueezeAction)? |
Callback for squeeze events (Apple Pencil Pro, iPadOS 17.5+) |
onError |
Function(dynamic)? |
Error callback |
TapAction
Represents a double-tap event on the Apple Pencil.
| Property | Type | Description |
|---|---|---|
preferredAction |
PreferredAction |
User's preferred action from Settings |
locationX |
double? |
X coordinate of hover position |
locationY |
double? |
Y coordinate of hover position |
zOffset |
double? |
Z-offset (0.0-1.0) - distance from screen |
SqueezeAction
Represents a squeeze event on Apple Pencil Pro. Extends TapAction.
| Property | Type | Description |
|---|---|---|
preferredAction |
PreferredAction |
User's preferred action from Settings |
squeezePhase |
SqueezePhase |
Current phase of the squeeze gesture |
locationX |
double? |
X coordinate of hover position |
locationY |
double? |
Y coordinate of hover position |
zOffset |
double? |
Z-offset (0.0-1.0) - distance from screen |
SqueezePhase
Enum representing the phase of a squeeze gesture.
| Value | Description |
|---|---|
began |
Squeeze gesture started |
changed |
Squeeze gesture is ongoing |
ended |
Squeeze gesture completed |
cancelled |
Squeeze gesture was cancelled |
unknown |
Unknown phase |
PreferredAction
Enum representing the user's preferred action as configured in iOS Settings.
| Value | Description |
|---|---|
ignore |
No action |
switchEraser |
Switch between current tool and eraser |
switchPrevious |
Switch between current and previous tool |
showColorPalette |
Show color palette |
showInkAttributes |
Show ink attributes (iOS 16.0+) |
showContextualPalette |
Show contextual palette (iOS 17.5+) |
runSystemShortcut |
Run system shortcut (iOS 17.5+) |
unknown |
Unknown action |
Example
See the example directory for a complete sample application demonstrating both double-tap and squeeze detection.
Topics
#apple-pencil #ipad #iphone-duo #stylus #gestures
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Libraries
- apple_pencil_double_tap
- Apple Pencil double-tap and squeeze callbacks for compatible iOS devices.
- apple_pencil_double_tap_method_channel
- Method-channel implementation of the Apple Pencil platform interface.
- apple_pencil_double_tap_platform_interface
- Platform interface for receiving native Apple Pencil gesture events.
- entities/preferred_action
- User-selected Apple Pencil actions reported by UIKit.
- entities/squeeze_action
- Apple Pencil Pro squeeze event data received from UIKit.
- entities/squeeze_phase
- Lifecycle phases of Apple Pencil Pro squeeze gestures.
- entities/tap_action
- Double-tap event data received from UIKit.