flutter_apple_pencil 1.0.0
flutter_apple_pencil: ^1.0.0 copied to clipboard
A Flutter plugin for detecting Apple Pencil interactions including double-tap and squeeze gestures.
flutter_apple_pencil #
A Flutter plugin for detecting Apple Pencil interactions including double-tap and squeeze gestures.
Features #
- ✅ Detect Apple Pencil double-tap gestures (Apple Pencil 2nd generation and later)
- ✅ Detect Apple Pencil squeeze gestures (Apple Pencil Pro)
- ✅ Real-time event streaming
- ✅ Support for iOS 12.1 and later
Platform Support #
| Platform | Supported |
|---|---|
| iOS | ✅ |
| Android | ❌ |
| Web | ❌ |
| macOS | ❌ |
| Windows | ❌ |
| Linux | ❌ |
Requirements #
- iOS 12.1 or later
- Apple Pencil (2nd generation) for double-tap
- Apple Pencil Pro for squeeze gesture
- Flutter 3.3.0 or later
Installation #
Add the dependency to your pubspec.yaml:
flutter pub add flutter_apple_pencil
Then run:
flutter pub get
Usage #
Basic Setup #
import 'package:flutter_apple_pencil/flutter_apple_pencil.dart';
// Create an instance
final applePencil = FlutterApplePencil();
// Check if Apple Pencil interactions are supported
final isSupported = await applePencil.isSupported();
if (isSupported) {
// Initialize the plugin
await applePencil.initialize();
// Listen to double-tap events
applePencil.onPencilDoubleTap.listen((PencilTap tap) {
print('Double-tap detected at ${tap.timestamp}');
if (tap.hoverPose != null) {
print('Hover z-offset: ${tap.hoverPose!.zOffset}');
}
});
// Listen to squeeze events (Apple Pencil Pro)
applePencil.onPencilSqueeze.listen((PencilSqueeze squeeze) {
print('Squeeze detected at ${squeeze.timestamp} (phase=${squeeze.phase})');
if (squeeze.hoverPose != null) {
print('Hover location: ${squeeze.hoverPose!.location}');
}
});
// Read user preference values (optional)
final preferredTap = await applePencil.preferredTapAction;
final preferredSqueeze = await applePencil.preferredSqueezeAction;
final pencilOnly = await applePencil.prefersPencilOnlyDrawing;
final hoverPreview = await applePencil.prefersHoverToolPreview;
}
// When done
applePencil.dispose();
Complete Example #
See the example directory for a complete sample application.
Cleanup #
Don't forget to dispose of the plugin when you're done:
@override
void dispose() {
applePencil.dispose();
super.dispose();
}
API Reference #
FlutterApplePencil #
Core plugin class to detect Apple Pencil interactions and query user preferences.
Methods & getters
Future<void> initialize()- Initialize native listeners and start streaming events.
Future<bool> isSupported()- Returns true when the current device and OS support Apple Pencil interactions.
Future<void> dispose()- Stop listeners and free native resources. Call from
dispose()in your widget.
- Stop listeners and free native resources. Call from
Stream<PencilTap> get onPencilDoubleTap- Stream that emits
PencilTapevents when the Apple Pencil double-tap occurs.
- Stream that emits
Stream<PencilSqueeze> get onPencilSqueeze- Stream that emits
PencilSqueezeevents for Apple Pencil Pro squeeze gestures.
- Stream that emits
Preference getters (async)
Future<PencilPreferredAction?> get preferredTapActionFuture<PencilPreferredAction?> get preferredSqueezeActionFuture<bool> get prefersPencilOnlyDrawingFuture<bool> get prefersHoverToolPreview
Event classes and enums
PencilTap
DateTime timestamp— when the tap was receivedPencilHoverPose? hoverPose— optional hover details (location, z-offset, angles)
PencilSqueeze
DateTime timestamp— when the squeeze occurredPencilInteractionPhase phase— the squeeze phase (began/changed/ended/cancelled)PencilHoverPose? hoverPose— optional hover details
PencilHoverPose
Offset location— position in logical pixelsdouble zOffset— Z distance from the screendouble altitudeAngle— altitude (radians)double azimuthAngle— azimuth (radians)double rollAngle— roll (radians), may be zero when not available
PencilPreferredAction (enum)
ignoreswitchEraserswitchPreviousshowColorPaletteshowInkAttributesshowContextualPaletterunSystemShortcut
PencilInteractionPhase (enum)
beganchangedendedcancelled
How It Works #
The plugin uses native iOS APIs to detect Apple Pencil interactions:
- Double-tap: Uses
UIPencilInteractiondelegate methods:- iOS 17.5+:
pencilInteraction(_:didReceiveTap:)(new API) - iOS 12.1-17.4:
pencilInteractionDidTap(_:)(deprecated but supported for backward compatibility)
- iOS 17.5+:
- Squeeze: Uses
pencilInteraction(_:didReceiveSqueeze:)on Apple Pencil Pro (iOS 17.5+)
The native code communicates with Flutter using Method Channels for initialization and Event Channels for streaming interaction events.
Limitations #
- Only works on iOS devices with Apple Pencil support
- Double-tap requires Apple Pencil (2nd generation) or later
- Squeeze requires Apple Pencil Pro
- The app must be in the foreground to receive events
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments #
Author #
👤 Filippo Finke
- Website: https://filippofinke.ch
- Twitter: @filippofinke
- GitHub: @filippofinke
- LinkedIn: @filippofinke