Description
The "force" property of UITouch is how Apple Pencil devices report pressure. This is in addition to other properties like altitudeAngle and azimuthAngleInView: .
Currently, the "force" property of the React Native side touch handler events (onTouchStart, onTouchMove, etc..) are only present in 3D Touch devices, but not devices supporting Apple Pencil. This is due to a check to BOOL RCTForceTouchAvailable() to check if force touch is available. However, this simple check is the reason that iPads cannot report Apple Pencil pressure.
The function is implemented here. The implementation checks for UITraitCollection's forceTouchCapability value to be equal to UIForceTouchCapabilityAvailable. This would seem like a very logical choice, however, iPad devices, even on devices which support Apple Pencils, and are paired to them, would report forceTouchCapability to be equal to UIForceTouchCapabilityUnavailable, causing this check to fail, and the pressure property to never be captured and sent to the React Native side.
I propose a fix by either
-
Removing the check for comparison to UIForceTouchCapabilityAvailable over here. The worst that could happen would just be 0 values for pressure on devices without any support for pressure.
-
Add another check at the RCTForceTouchAvailable() call here to check if the touch is a stylus touch, like the following:
From
if (RCTForceTouchAvailable()) {
to
if (RCTForceTouchAvailable() || nativeTouch.type == UITouchTypeStylus) {