Search code examples
iphoneuitouchpressure

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


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?


Solution

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