Is there any way at all that I can tell how hard the screen is being pressed
Asked Answered
H

4

13

I want to find the pressure of the touch. I just don't know how to accomplish that result with out jailbreaking it and getting the raw touch data. Does anyone know How I would do this?

Hydrant answered 20/1, 2010 at 17:26 Comment(2)
So how do you detect if the screen is broken then?Wahl
apple must use something like this to determine the velocity in the garage band app.Deprive
A
28

You cannot get the pressure from the SDK nor undocumented methods. However you can detect the size of touch with undocumented methods.


In the GSEvent, which is a lower-level representation of UIEvent, there is a structure known as GSPathInfo with members:

typedef struct GSPathInfo {
    unsigned char pathIndex;        // 0x0 = 0x5C
    unsigned char pathIdentity;     // 0x1 = 0x5D
    unsigned char pathProximity;    // 0x2 = 0x5E
    CGFloat pathPressure;               // 0x4 = 0x60
    CGFloat pathMajorRadius;        // 0x8 = 0x64
    CGPoint pathLocation;           // 0xC = 0x68
    GSWindowRef pathWindow;         // 0x14 = 0x70
} GSPathInfo;

We notice that there is a pathPressure and pathMajorRadius. I can assure you the pressure member is useless – it always gives 0. However pathMajorRadius does contain meaningful information – it gives the major radius of the touch in millimeters. You can therefore give an extremely rough estimation if it's a heavy touch or light touch from the radius.

  -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
     GSEventRef gsevent = [event _gsEvent];
     GSPathInfo first_touch = GSEventGetPathInfoAtIndex(gsevent, 0);
     if (first_touch.pathMajorRadius >= 9)
        NSLog(@"huge (heavy) touch");
     else
        NSLog(@"little (light) touch");
  }

Let me warn you again this is undocumented and you should not use it in AppStore apps.


Edit: On 3.2 and above the pathMajorRadius of a GSPathInfo is also available as an undocumented property in UITouch:

@property(assign, nonatomic, setter=_setPathMajorRadius:) CGFloat _pathMajorRadius;

so the code above could be rewritten using pure Objective-C:

  -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
     UITouch* any_touch = [touches anyObject];
     if (any_touch._pathMajorRadius >= 9)
        NSLog(@"huge (heavy) touch");
     else
        NSLog(@"little (light) touch");
  }
Archbishop answered 20/1, 2010 at 18:3 Comment(7)
Would apple reject the app for that reason. Because it is undocumented?Hydrant
@Jaba: Yes. To use GSEventGetPathInfoAtIndex you'll need to link to the private framework GraphicsServices. Even if you do late binding, Apple will still find the strings _gsEvent and GSEventGetPathInfoAtIndex and reject that.Archbishop
Is there a backdoor that I could explore, like another way to get this to work, or could I access this private file through another pathway?Hydrant
Wow, that's pretty damn cool. But if you use it you can guarantee yourself a nice little rejection.Holocene
@Jaba: You could "encode" your binary like Skype did (not that Skype uses undocumented methods though). But I don't think it worths the effort. And this solution isn't very accurate either, consider a fat finger...Archbishop
Is this still true? If so - are you saying there's no App-Store-approved way of detecting how hard the screen was touched? Because there are apps out there such as Virtuoso (virtual piano) that definitely achieve just that...Wellknit
@yonix: Probably it uses jminor's method.Archbishop
F
13

As of iOS 8.0, UITouch has a public majorRadius property which tells you the approximate size of the touch.

Fraudulent answered 25/8, 2014 at 18:23 Comment(0)
V
12

In iOS 3.2 and 4.0 you can get the value more directly like this:

UITouch* touch = ...// get the touch object
float radius = [[touch valueForKey:@"pathMajorRadius"] floatValue];

Still not App Store approved, but handy for custom stuff.

Venous answered 9/7, 2010 at 18:59 Comment(2)
What do you mean still not App Store approved? Will Apple reject my app if I use it? (if so, how do apps like Virtuoso Piano achieve this?)Wellknit
Some apps try to use the accelerometer to measure how "hard" the user taps the screen. I'm not sure about Virtuoso Piano. As far as I know there is still no Apple review policy approved way to get at the touch radius information described in this article.Venous
H
1

It's not possible with the SDK. It does not expose that data in anyway. And the screen does not sense pressure, and wether it even reports touch "size" to the OS is unknown. So sadly, what you are trying to do is not possible on a legit application.

I know because I asked the same thing: Can the iPhone detect the size of a touch?

Holocene answered 20/1, 2010 at 17:29 Comment(2)
It does sense the size of the touch but the information is discarded. See my answer.Archbishop
@Kenny: where is your answer and can i access the discarded information, and use it in the app without it being rejected?Hydrant

© 2022 - 2024 — McMap. All rights reserved.