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

Jab picture Jab · Jan 20, 2010 · Viewed 9.1k times · Source

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?

Answer

kennytm picture kennytm · Jan 20, 2010

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");
  }