How to get touch size in iOS?

2019-03-20 12:15发布

I understand that this response clearly states that this is not possible without a private function call. Therefore, according to Apple's terms, this approach cannot be used on an App Store app.

However, some apps already seem to use this function call:

  • Penultimate for actual palm rejection without a predefined rejection area like in Note Taker HD
  • Virtuoso for pressure sensitivity, which they call "TrueVelocity 2"
  • GarageBand also for pressure sensitivity

Clearly, this approach is already widely used in App Store apps despite Apple's restrictions.

tl;dr What is the private function call on iOS to get touch size?

标签: ios size touch
4条回答
萌系小妹纸
2楼-- · 2019-03-20 12:36

Size and pressure are two different animals. Penultimate most likely tests for a large amount of touches in a certain area (palms have a large area after all, generate tons of touches).

Touch "size" does not exist. IOS touch events are generated when a finger contacts the screen. The OS then takes a center point from the touch and that's what you get. It's not a CGRect, it's a CGPoint.

Pressure is 'easier' though. see here for a workaround: Tap pressure strength detection using accelerometer

And while I see you're in the market for private API's, github hosts a number of class dumps: http://github.com/kennytm/iphone-private-frameworks and https://github.com/nst/iOS-Runtime-Headers

查看更多
家丑人穷心不美
3楼-- · 2019-03-20 12:45

With iOS8, you can access the touch.majorRadius property, which is a CGFloat, grows in multiples of 10.45 and is proportional to the radius of the touched area in Millimeters. touch.majorRadiusTolerance is the second property which can be used with iOS8 and gives the accuracy of the touch radius information. In my measurements it was always half of the majorRadius step size.

On the iPad Pro the touchscreen is three times more sensitive and picks up the weak signal from the Apple pencil which is below the reporting threshold on older iPad models. The touch radius of the Pencil is reported as 0.25, while even the slightest finger contact will report as 20.84 or more.

Use it like this within your UIView method:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

// Regular multitouch handling.
    [super touchesBegan:touches withEvent:event];

    CGPoint center = [touch locationInView:self];
    NSLog(@"Touch detected at %6.1f | %6.1f", center.x, center.y);
    CGFloat radius = [touch majorRadius];
    NSLog(@"Radius = %5.1f; lower limit = %5.1f; upper limit = %5.1f", radius, radius-touch.majorRadiusTolerance, radius+touch.majorRadiusTolerance);
}
查看更多
该账号已被封号
4楼-- · 2019-03-20 12:53

If you're interested in the private (i.e., don't submit this to the app store method, you're looking for -

@interface UITouch (Private)
-(float)_pathMajorRadius;
@end

In my (private!) use of this, 10 was a good threshold for determining when a person was using their finger/stylus or resting their hand on the device.

Hope this is helpful to someone. Again, don't use this in the App Store.

查看更多
beautiful°
5楼-- · 2019-03-20 12:58

FYI looks like iOS 8 introduced a couple properties for estimating the radius of a UITouch: majorRadius and majorRadiusTolerance.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITouch_Class/index.html

查看更多
登录 后发表回答