Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 08-18-2008, 06:52 PM   #1 (permalink)
New Member
 
Join Date: May 2008
Posts: 38
torynfarr is an unknown quantity at this point
Default Single Tap / Double Tap

If I want my application to do something when the screen is single tapped (touch.tapCount == 1) and something different when the screen is double tapped (touch.tapCount == 2), what is the best way of handling this?

I want the actions that the single tap triggers to only occur when the screen is single tapped. I don't want double tapping the screen to do both the single tap action *and* the double tap actions.

Is there a way to do this without using an NSTimer? Right now, I've got an NSTimer that starts in the touchesEnded event method if the tap count is equal to 1. Also in the touchesEnded event method is code that... if the tapCount is greater than 1, invalidates the timer. I have the timer duration set to 0.25 seconds. This works... but I'd like a more elegant solution.

-Toryn
torynfarr is offline   Reply With Quote
Old 08-18-2008, 07:42 PM   #2 (permalink)
New Member
 
Join Date: Apr 2008
Posts: 802
scottiphone is on a distinguished road
Default

The iPhone Programming Guide on Apple's site specifically gives snippets to deal with this.
scottiphone is offline   Reply With Quote
Old 08-20-2008, 09:13 PM   #3 (permalink)
New Member
 
Join Date: May 2008
Posts: 38
torynfarr is an unknown quantity at this point
Default

Quote:
Originally Posted by scottiphone View Post
The iPhone Programming Guide on Apple's site specifically gives snippets to deal with this.
Where? Where are there "specifically" snippets that deal with this?

In here?

iPhone Dev Center

... because I couldn't see anything that specifically addressed my question.

Could you do me a favor and not reply to my threads any more? I don't want to argue with you or start a silly flame war or something. But these one sentence replies are not very helpful or productive. And you don't just do them to me.. you reply to like everyone's question like this.
torynfarr is offline   Reply With Quote
Old 08-20-2008, 11:00 PM   #4 (permalink)
New Member
 
Join Date: Apr 2008
Posts: 802
scottiphone is on a distinguished road
Default

Page 145 iPhone Programming Guide - This should the first pdf people read after learning Objective-C

HandlingSingleandMultipleTapGestures
AverycommongestureiniPhoneapplicationsisthetap:the usertapsanobjectwithhisorherfinger.
Aresponderobjectcanrespondtoasingletapinoneway,ado uble-tapinanother,andpossiblya
triple-tapinyetanotherway.Todeterminethenumberoftimestheu sertappedaresponderobject,
yougetthevalueofthetapCountpropertyofaUITouchobjec t.
ThebestplacestofindthisvaluearethemethodstouchesBe gan:withEvent:and
touchesEnded:withEvent:.Inmanycases,thelattermetho dispreferredbecauseitcorrespondsto
thetouchphaseinwhichtheuserliftsafingerfromatap.By lookingforthetapcountinthetouch-up
phase(UITouchPhaseEnded),youensurethatthefingerisr eallytappingandnot,forinstance,touching
downandthendragging.
144 HandlingMulti-TouchEvents
2008-07-08 | ©2008AppleInc. AllRightsReserved.

In Listing 7-1, the touchesEnded:withEvent: method implementation responds to a double-tap
gesture by zooming in on (or out from) the content shown in a scroll view.
Listing 7-1 Handling a double-tap gesture
- (void) touchesEndedNSSet*)touches withEventUIEvent*)event
{
UIScrollView *scrollView = (UIScrollView*)[self superview];
UITouch *touch = [touches anyObject];
CGSize size;
CGPoint point;
if([touch tapCount] == 2) {
if(![_viewController _isZoomed]) {
point = [touch locationInView:self];
size = [self bounds].size;
point.x /= size.width;
point.y /= size.height;
[_viewController _setZoomed:YES];
size = [scrollView contentSize];
point.x *= size.width;
point.y *= size.height;
size = [scrollView bounds].size;
point.x -= size.width / 2;
point.y -= size.height / 2;
[scrollView setContentOffsetoint animated:NO];
}
else
[_viewController _setZoomed:NO];
}
}
A complication arises when a responder object wants to handle a single-tap and a double-tap gesture
in different ways. For example, a single tap might select the object and a double tap might display a
view for editing the item that was double-tapped. How is the responder object to know that a single
tap is not the first part of a double tap? Here is how a responder object could handle this situation
using the event-handling methods just described:
1. In touchesEnded:withEvent:, when the tap count is one, the responder object sends itself a
performSelector:withObject:afterDelay: message. The selector identifies another method
implemented by the responder to handle the single-tap gesture; the object for the second parameter
is the related UITouch object; the delay is some reasonable interval between a single- and a
double-tap gesture.
2. In touchesBegan:withEvent:, if the tap count is two, the responder object cancels the pending
delayed-perform invocation by sending itself a cancelPreviousPerformRequestsWithTarget:
message. If the tap count is not two, the method identified by the selector in the previous step
for single-tap gestures is invoked after the delay.
3. In touchesEnded:withEvent:, if the tap count is two, the responder performs the actions necessary
for handling double-tap gestures.
C H A P T E R 7
Event Handling
scottiphone is offline   Reply With Quote
Old 08-21-2008, 05:27 AM   #5 (permalink)
Registered Member
 
craig t mackenzie's Avatar
 
Join Date: Aug 2008
Location: London, UK
Age: 25
Posts: 53
craig t mackenzie is on a distinguished road
Send a message via AIM to craig t mackenzie
Default

Quote:
Originally Posted by torynfarr View Post
Could you do me a favor and not reply to my threads any more? I don't want to argue with you or start a silly flame war or something. But these one sentence replies are not very helpful or productive. And you don't just do them to me.. you reply to like everyone's question like this.
With all due respect a lot of questions can easily be answered yourself (and myself, and all of ourselves) by being gently nudged in the right direction.

Sometimes we don't have enough time to write an essay response to every question asked, but know roughly where the right info is in the (mountains) of professionally written documentation Apple Provides.

I can understand how frustrating learning new things can be, but to be so rude to another member of the community isn't an option in my opinion.

Perhaps you could explain more clearly what you're after, so other people can help?
craig t mackenzie is offline   Reply With Quote
Old 08-21-2008, 05:31 AM   #6 (permalink)
Registered Member
 
craig t mackenzie's Avatar
 
Join Date: Aug 2008
Location: London, UK
Age: 25
Posts: 53
craig t mackenzie is on a distinguished road
Send a message via AIM to craig t mackenzie
Default

maybe this thread could help:

http://www.iphonedevsdk.com/forum/ip...che-click.html
craig t mackenzie is offline   Reply With Quote
Old 08-21-2008, 05:33 AM   #7 (permalink)
Registered Member
 
Stitch's Avatar
 
Join Date: Aug 2008
Posts: 400
Stitch is on a distinguished road
Default

Quote:
Originally Posted by torynfarr View Post
Could you do me a favor and not reply to my threads any more? I don't want to argue with you or start a silly flame war or something. But these one sentence replies are not very helpful or productive. And you don't just do them to me.. you reply to like everyone's question like this.
Are you being serious? That one line reply given to you (with an hour of posting) told you everything you needed apart from the page number.

The best thing you can do right now, if you haven't already is to download all of the pdf documents available and keep them locally. You'll answer most of your own questions very quickly by just doing a search. They are invaluable.
Stitch is offline   Reply With Quote
Old 08-21-2008, 10:18 AM   #8 (permalink)
New Member
 
Join Date: May 2008
Posts: 38
torynfarr is an unknown quantity at this point
Default

Honestly, one line responses aren't helpful.

I don't understand what the point of replying to someone's question is when you just shoot out one line responses, telling the person to "look it up in the documentation"

I already looked at the SDK documentation and the PDF mentioned. There are no snippets of code that specifically address handling separate actions for a single tap and double tap.

The only thing in that PDF that pertains to my question is:

"1. In touchesEnded:withEvent:, when the tap count is one, the responder object sends itself a
performSelector:withObject:afterDelay: message. The selector identifies another method
implemented by the responder to handle the single-tap gesture; the object for the second parameter
is the related UITouch object; the delay is some reasonable interval between a single- and a
double-tap gesture. "

And that sounds like it still involves using an NSTimer (for the delay portion)?



I see these one line responses from (only a few people) all the time, and I think it's a detriment to this development community. I'm not expecting long essays or even examples of code for every single question that people ask. But suggestions other than "look it up in the documentation" are a lot more productive than this.

That being said, yes... sometimes people ask questions that are so general... or so very clear that they haven't attempted to find the answer on their own. Politely pointing them to the documentation makes sense. But given that my question in this case was specific, and that I have it working already using an NSTimer, and I'm just looking for a more elegant solution (one that doesn't involve using a timer)... I think one could infer from that.... that I've read the documentation.

I'm not the only one here who has gotten frustrated at replies like that. I've seen a lot of other questions posted that are well stated, with examples of the problem, source code, etc. etc. and get very dismissive replies.
torynfarr is offline   Reply With Quote
Old 08-21-2008, 10:53 AM   #9 (permalink)
Nos
Registered Member
 
Join Date: Aug 2008
Posts: 132
Nos is on a distinguished road
Default

I have the same problem.
I would like my application do something when the screen is single tapped (touch.tapCount == 1) and nothing when the screen is double tapped (touch.tapCount == 2) or more.
But, the problem is : when the screen is double tapped or more, the app execute the first tap.
How can I resolve this ?
Nos is offline   Reply With Quote
Old 08-21-2008, 11:46 AM   #10 (permalink)
Registered Member
 
Jume's Avatar
 
Join Date: Jul 2008
Location: Slovenia, EU
Posts: 264
Jume is on a distinguished road
Send a message via Skype™ to Jume
Default

Quote:
Originally Posted by Nos View Post
I have the same problem.
I would like my application do something when the screen is single tapped (touch.tapCount == 1) and nothing when the screen is double tapped (touch.tapCount == 2) or more.
But, the problem is : when the screen is double tapped or more, the app execute the first tap.
How can I resolve this ?
first check for double (or triple or more) taps and exit if true.. else you have a single tap.
Jume is offline   Reply With Quote
Old 08-22-2008, 03:27 AM   #11 (permalink)
Nos
Registered Member
 
Join Date: Aug 2008
Posts: 132
Nos is on a distinguished road
Default

It doesn't work. It always executes the first tap action even if you tap a second or more time.
Nos is offline   Reply With Quote
Old 09-07-2008, 09:51 AM   #12 (permalink)
Registered Member
 
Join Date: Aug 2008
Location: Germany, Munich
Posts: 246
rhuettl is on a distinguished road
Default

Hi guys,

i think you are missunderstanding the initial question. He is not asking how double tap (with two fingers and maybe on different points) is working - there are many examples showing this.

He (and me too) likes to know how a double tap (like a mouse double klick) can be handled - means: two tips on THE SAME point/position in a specified delta of time (0.25 seconds or below) occured.

I think you have to measure the delta between the first touch end and the second one. If the point on these two touches are the same (+/- a delta of some pixels) and the time delta is < 250msec then you are in a double tap.

But you have to solve one problem. If you handle a one tap and a double tap you should suspense the one tap until >= 250msec so that you know that there no douple tap will occur.

Any implementation examples out?

Cheers
Ralf
rhuettl is offline   Reply With Quote
Old 09-07-2008, 11:14 AM   #13 (permalink)
Registered Member
 
Join Date: Aug 2008
Location: Germany, Munich
Posts: 246
rhuettl is on a distinguished road
Default

Ah, by the way:
Where is the performselector:withobject:afterDelay function? If i look at the docs i cant find one with the afterDeley parameters...

:-) Ralf
rhuettl is offline   Reply With Quote
Old 09-07-2008, 05:01 PM   #14 (permalink)
New Member
 
Join Date: Sep 2008
Posts: 1,431
PhoneyDeveloper is on a distinguished road
Default

Quote:
Where is the performselector:withobject:afterDelay function? If i look at the docs i cant find one with the afterDeley parameters...
Are you really saying that you don't know how to use the Find window?

Open the multifile find window. Type into the find box: performSelector. Select 'Find in Frameworks'. Click the Find button. You will see numerous results. A few of them will also include afterDelay.

Open the header file that has the result you want in it. Option-double-click on the performSelector text in the header file and the appropriate doc will open.

If you didn't know this stuff you need to read the Xcode documentation. You will never be productive if you can't find functions in the header files and in the docs from their names.

BTW, to the OP, your code doesn't need to deal with timers if it uses performselector:withobject:afterDelay
PhoneyDeveloper is offline   Reply With Quote
Old 06-21-2009, 02:34 AM   #15 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 50
rnieves is on a distinguished road
Default

That stuff in the programming guide actually does work, it sounds great but I want to be able to send the event and the touch to the singleTap method since this will forward it if necessary to another responder. I cannot do this with this solution.


I have tried using a timer but there seems to be a problem. Can anybody tell me what might be wrong.

In my touchesBegan method I did
Code:
	if ([doubleTapTimer isValid]) {
		[doubleTapTimer invalidate];
		doubleTapTimer = nil;
	}
	if(![doubleTapTimer isValid]) {
		[self startTouchTimer:DOUBLE_TAP_TIMER withTouch:touches andEvent:event];
	} else if (tapCount == 2) {
		if(self.zoomedView) {
			[self resetScrollZoom];
		} else {
			[super touchesBegan:touches withEvent:event];
		}
		[doubleTapTimer invalidate];
		doubleTapTimer = nil;
		return;
	}
Then in my startTouchTimer method I prepare my timer with an invocation to call the singleTapMethod.

Code:
//Prepare invocation
	SEL singleTapSelector = @selector(singleTapDone:withEvent:);  //selector
	NSMethodSignature * sig = [[self class] instanceMethodSignatureForSelector:singleTapSelector]; //signature to initialize
	NSInvocation *singleTapObjects = [NSInvocation invocationWithMethodSignature:sig]; //initialize selector
	[singleTapObjects setTarget:self];
	[singleTapObjects setSelector:singleTapSelector];
	[singleTapObjects setArgument:&touches atIndex:2];		//set parameters for invocations
	[singleTapObjects setArgument:&event atIndex:3];
	
	
	doubleTapTimer = [NSTimer scheduledTimerWithTimeInterval:delay invocation:singleTapObjects repeats:NO];
This successfully calls the singleTapMethod and when looking at the debugger the objects passed are the same (location wise) but when calling [super touchesBegan:withEvent] on this method it does not handle it at all. Nothing happens. If I just implement the [super touchesBegan:withEvent] on the touchesBegan method it successfully handles it by forwarding it.

BTW already tried using self.nextResponder to try and force it myself to forward the touchesBegan but it won't work either.


Edit:

I did some more research and although the touch and event do get forwarded, when getting to the touchesBegan on the subview they have been forwarded to the reason they don't work is because getting the coordinates and/or the tapCount returns cero for the touch. Can anybody please shed some light on this situations?
rnieves is offline   Reply With Quote
Old 09-17-2009, 01:50 PM   #16 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 26
jarson is on a distinguished road
Default

This code works great for me ( I go up to triple taps here):

Code:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	NSUInteger numTaps = [[touches anyObject] tapCount];
	if (numTaps < 2) {
		[self performSelector:@selector(doThis) withObject:nil afterDelay: 0.5 ];
		
		[self.nextResponder touchesEnded:touches withEvent:event];
	} else {
		if(numTaps == 2) {
			[NSObject cancelPreviousPerformRequestsWithTarget:self];

			[self performSelector:@selector(doSomethingElse) withObject:nil afterDelay: 0.5 ];
		}		

		if(numTaps == 3){
			//				NSLog(@"3 taps - Previous");

			[NSObject cancelPreviousPerformRequestsWithTarget:self];

			[self doSomethingElseCompletely];
			
		}
	}
	
}
Only thing is I wish I could increase the tap-area, but I'll start a new topic for that.
jarson is offline   Reply With Quote
Old 06-28-2011, 01:52 PM   #17 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 7
artaxerxes is on a distinguished road
Thumbs up

Thanks all - this thread was just the inspiration i needed to overcome the issue I had with single and double taps triggering at the same instance.
artaxerxes is offline   Reply With Quote
Old 06-28-2011, 01:56 PM   #18 (permalink)
Nuisance Developer
 
Join Date: Jul 2009
Location: Italy
Posts: 4,691
dany_dev is on a distinguished road
Default

also UIGesture might interest you.
__________________
dany_dev is offline   Reply With Quote
Old 06-28-2011, 03:18 PM   #19 (permalink)
Flash Developer
 
Join Date: Mar 2011
Location: Norway
Posts: 77
thh022 is on a distinguished road
Default

To handle one tap...

h-file:

Code:
UITapGestureRecognizer *tapGestureRecognizer;

@property(nonatomic, retain) UITapGestureRecognizer *tapGestureRecognizer;
m-file:

Code:
@synthesize tapGestureRecognizer;

// VIEWDIDLOAD
UITapGestureRecognizer *newTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTaps:)];
self.tapGestureRecognizer = newTapGestureRecognizer;
self.tapGestureRecognizer.numberOfTouchesRequired = 1;
self.tapGestureRecognizer.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:self.tapGestureRecognizer];
[newTapGestureRecognizer release];

// FUNCTION CALLED WHEN SCREEN IS TAPPED ONCE
-(void)handleTaps:(UITapGestureRecognizer*)paramSender{
}
thh022 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 324
13 members and 311 guests
chiataytuday, coolman, givensur, glenn_sayers, guusleijsten, ipodphone, jbro, mediaspree, mottdog, mtl_tech_guy, Punkjumper, vilisei, whitey99
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,114
Posts: 402,883
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 09:29 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0