Question

I have a UIButton which has an IBAction as well as a UITapGestureRecognizer to detect double taps.

At the moment it looks like the IBAction is blocking the recognizer. Is there a way to stop this or do UITapGestureRecognizer even work on buttons? If so wouldn't it be better to just add the recognizers and remove the IBActions?

EDIT

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[A1 addGestureRecognizer:doubleTap];
[A2 addGestureRecognizer:doubleTap];
[B1 addGestureRecognizer:doubleTap];
Was it helpful?

Solution

Looks like you are trying to attach one gesture recognizer to multiple buttons. A gesture recognizer can only be attached to one view at a time. So in your case, the last button you are attaching the recognizer to (button B1) probably responds to the double tap but A1 and A2 don't.

Create a separate recognizer for each button.
But all three recognizers can call the same action method (handleDoubleTap:).

However, when you try to do a single tap on a button, there will be a slight delay as it waits to see if it's the beginning of a double tap. There are ways to reduce the delay but may not be worth it if you can live with the delay and the workarounds bring up other issues.

Edit:
In your comment, you say you "want to detect if they are pressed at the same time". To do this, you don't need gesture recognizers. You can just use the standard control events provided.

Next, in IB, for each button, hook up the "Touch Down" event with buttonPressed:. Or, to do it programmatically:

[button1 addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
[button2 addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
[button3 addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];

Next, in IB, for each button, hook up the "Touch Up Inside" and "Touch Up Outside" events with buttonReleased:. Or, to do it programmatically:

[button1 addTarget:self action:@selector(buttonReleased:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside];
[button2 addTarget:self action:@selector(buttonReleased:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside];
[button3 addTarget:self action:@selector(buttonReleased:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside];

Next, add ivars to keep track of how many or which buttons are pressed:

@property (nonatomic) int numberOfButtonsBeingTouched;
@property (strong, nonatomic) NSMutableSet *buttonsBeingTouched; //alloc + init in viewDidLoad or similar

If you just care how many buttons are pressed, you don't need the NSMutableSet.

Finally, add the buttonPressed and buttonReleased methods:

- (IBAction)buttonPressed:(UIButton *)button {
    self.numberOfButtonsBeingTouched++;
    [self.buttonsBeingTouched addObject:button];
    //your logic here (if (self.numberOfButtonsBeingTouched == 3) ...)
}

- (IBAction)buttonReleased:(UIButton *)button {
    self.numberOfButtonsBeingTouched--;
    [self.buttonsBeingTouched removeObject:button];
    //your logic (if any needed) here
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top