Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
503 views
in Technique[技术] by (71.8m points)

iphone - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...