How to Differentiate Whether a User Is Tapping the Screen with His Finger or an Apple Pencil

How to differentiate whether a user is tapping the screen with his finger or an apple pencil?

To check if a UITouch is using the stylus touch type in Objective-C:

if (touch.type == UITouchTypeStylus) {
// Do stuff
}

If you're not handling touches directly, but using a gesture recognizer, then it is a little more complicated.

You could try adding a second long press gesture recogniser and setting the allowedTouchTypes property on each one to recognise stylus or direct touches:

longPressGestureFinger.allowedTouchTypes = @[@(UITouchTypeDirect)];
longPressGesturePencil.allowedTouchTypes = @[@(UITouchTypeStylus)];

If that doesn't work, you would have to add a delegate to the long press gesture, and in the gestureRecognizer: shouldReceiveTouch: method, check and store the type of touch and use this when the gesture action fires.

Javascript touch event: distinguishing finger vs. Apple Pencil

The TouchList object of a touch event contains detailed information about the touch’s individual points. Among the many properties touchType is probably the most interesting for you as it contains either "stylus" (Apple Pencil) or "direct" (finger).

var body = document.querySelector('body');
body.addEventListener('touchstart', function(evt){
// should be either "stylus" or "direct"
console.log(evt.touches[0].touchType);
});

You should also have a look at the other properties of each individual Touch like force or azimuthAngle that can give you detailed information about the touch point’s current device(s).

Please note that the Touch interface is only part of a W3C working
draft and not official standard yet – however works in iOS 10 +
Safari + Apple Pencil.

Detect whether Apple Pencil is connected to an iPad Pro

I can't find any actual documentation on the Apple Pencil's Bluetooth
implementation (and I don't believe any exists), but the following code Works
for Me™.

It checks for connected devices that advertise themselves as supporting the
"Device Information" service and then if any of these have the name "Apple
Pencil".

PencilDetector.h

@import CoreBluetooth

@interface PencilDetector : NSObject <CBCentralManagerDelegate>

- (instancetype)init;

@end

PencilDetector.m

#include "PencilDetector.h"

@interface PencilDetector ()

@end

@implementation PencilDetector
{
CBCentralManager* m_centralManager;
}

- (instancetype)init
{
self = [super init];
if (self != nil) {
// Save a reference to the central manager. Without doing this, we never get
// the call to centralManagerDidUpdateState method.
m_centralManager = [[CBCentralManager alloc] initWithDelegate:self
queue:nil
options:nil];
}

return self;
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn)
{
// Device information UUID
NSArray* myArray = [NSArray arrayWithObject:[CBUUID UUIDWithString:@"180A"]];

NSArray* peripherals =
[m_centralManager retrieveConnectedPeripheralsWithServices:myArray];
for (CBPeripheral* peripheral in peripherals)
{
if ([[peripheral name] isEqualToString:@"Apple Pencil"])
{
// The Apple pencil is connected
}
}
}
}

@end

In practice, the following, simpler, synchronous code, which doesn't wait for
the central manager to be powered on before checking for connected devices
seems to work just as well in my testing. However, the documentation states that you shouldn't
call any methods on the manager until the state has updated to be
CBCentralManagerStatePoweredOn, so the longer code is probably safer.

Anywhere you like

m_centralManager = [[CBCentralManager alloc] initWithDelegate:nil
queue:nil
options:nil];

// Device information UUID
NSArray* myArray = [NSArray arrayWithObject:[CBUUID UUIDWithString:@"180A"]];

NSArray* peripherals =
[m_centralManager retrieveConnectedPeripheralsWithServices:myArray];
for (CBPeripheral* peripheral in peripherals)
{
if ([[peripheral name] isEqualToString:@"Apple Pencil"])
{
// The Apple pencil is connected
}
}

Apple pencil click on button or anchor element not working on webapplication

I could not find a proper solution for this. But I have tried this and this seems like working find

$(window).bind('touchstart', function(e) {
e.target.click();
});

Web - How to differentiate between finger touch and stylus touch?

You can tell with fairly high confidence if a touch is by finger or stylus by capturing the PointerEvent and checking its width and height properties, which represent the tip size.

A stylus typically has a smaller width and height than a finger.



Training an App to Recognize Finger vs. Stylus

Since tip size likely varies between screens, fingers, and styluses, a possible strategy would be to have the user train the app to recognize different types of touches:

"This is a finger" command, followed by several finger touches until the app has a good sample of sizes.

"This is a stylus" command, followed by several stylus touches.

MDN on PointerEvent interface.

Demo that shows stylus (or finger) tip size of every screen touch.

This will display the tip size of a touch or click on the screen:

let counter = 0;// listen for 'pointerdown' events, detect tip sizewindow.addEventListener('pointerdown', (evt) => {  const w = Number(evt.width).toFixed(1);  const h = Number(evt.height).toFixed(1);  const div = document.getElementById('result');  counter++;  div.innerHTML = `${counter}: stylus width: ${w}, height: ${h}`;});
body {  background-color: #eee;  color: black;}
#result { margin: 0.5rem; width: 18rem; min-height: 2rem; padding: 0.5rem; border: 1px solid gray; color: green;}
<h4>Test of Pointer Stylus Tip Size</h4><p>Touch or click anywhere...</p><div id="result"></div>


Related Topics



Leave a reply



Submit