On 28/06/2012, at 5:31 PM, Quincey Morris wrote:

> On Jun 28, 2012, at 00:14 , Graham Cox wrote:
> 
>> Specifically, the problem is that the -clickCount property of an NSEvent is 
>> only applicable to mouse events, not touch events. So what's the right way 
>> to trap this specific gesture? I have read the various touch-input 
>> documentation but nothing became obvious.
> 
> The 10.6 document seems to imply that tapping isn't a gesture, so I'd assume 
> you'd have to implement the NSResponder methods 'touches…WithEvent:' and use 
> the event times to decide (a) if precisely 2 touches begin/end more or less 
> simultaneously and (b) if a second 2-touch tap begins within a time interval 
> after the 1st one [iOS defaults to 0.5 sec for this interval. Perhaps on the 
> Mac you'd use something conditioned by the double-click time instead. I 
> dunno.] and (c) if both 2-touch taps last less than some time interval 
> [otherwise they'd represent a long press].
> 
> Something like that?
> 
> 


OK, that's pretty much what I'm doing, but it doesn't work all that well yet. 
The gesture is recognised, but only sometimes, so the effect for the user is 
that the gesture response is flaky.

I'm not sure what I need to do to improve this.

I've written a system somewhat similar (but simpler) than the iOS gesture 
recognizer system, where each gesture is recognized by an object, and as soon 
as it recognizes the gesture, it informs its delegate and tells the other 
recognizers in the set to fugeddaboudit. But in fact, I only have the one 
recognizer in there.

Here's the code, which happens to be in my recognizer object, but this can be 
thought of as being implemented by a view:

- (void)        touchesBeganWithEvent:(NSEvent*) event
{
        NSSet* touches = [event touchesMatchingPhase:NSTouchPhaseBegan 
inView:self.view];
        
        if([touches count] == 2 )
        {
                if( self.state == DKWaitingForTap )
                {
                        mFirstTapTime = [NSDate timeIntervalSinceReferenceDate];
                        [NSTimer scheduledTimerWithTimeInterval:[NSEvent 
doubleClickInterval] + 0.1 target:self selector:@selector(timeOut:) 
userInfo:nil repeats:NO];
                        self.state = DKGotFirstTap;
                }
                else if( self.state == DKGotFirstTap )
                {
                        NSTimeInterval dt = [NSDate 
timeIntervalSinceReferenceDate] - mFirstTapTime;
                        
                        if( dt <= [NSEvent doubleClickInterval])
                        {
                                self.state = DKGotSecondTap;
                                [self notifyDelegate];          // will 
eventually call -reset which puts the state back if timer or ended event 
doesn't do it first
                        }
                }
        }
}


- (void)        touchesEndedWithEvent:(NSEvent *)event
{
        if( self.state != DKWaitingForTap )
        {
                NSTimeInterval dt = [NSDate timeIntervalSinceReferenceDate] - 
mFirstTapTime;
                
                if( dt > [NSEvent doubleClickInterval])
                        [self reset];
        }
}


- (void)        touchesMovedWithEvent:(NSEvent*) event
{
        [self reset];
}


- (void)        touchesCancelledWithEvent:(NSEvent*) event
{
        [self reset];
}


- (void)        reset
{
        self.state = DKWaitingForTap;
}


- (void)        timeOut:(NSTimer*) timer;
{
        [self reset];
}


As you can see, I don't bother to track the touches - I only determine that 
there are two, and use a simple state machine to detect a double-tap. On the 
second tap the touches will be new objects anyway, so there isn't any mileage 
in trying to match them up with the touches of the first event. There's also a 
timer that resets the state if the second tap is never received.

It works, but since the results are flaky, this is obviously not good enough. 
Has anyone actually implemented something like this, and can see where I have 
gone wrong?


--Graham


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to