19

How to recognize double touch on UIButton ?

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • 3
    Double touching is not a standard, nor an obvious UIButton behavior. You should reconsider why you're needing this action. – Gavin Miller Nov 05 '10 at 20:05

5 Answers5

48

Add an target-action for the control event UIControlEventTouchDownRepeat, and do action only when the touch's tapCount is 2.

Objective-C:

[button addTarget:self action:@selector(multipleTap:withEvent:) 
             forControlEvents:UIControlEventTouchDownRepeat];

...

-(IBAction)multipleTap:(id)sender withEvent:(UIEvent*)event {
   UITouch* touch = [[event allTouches] anyObject];
   if (touch.tapCount == 2) {
     // do action.
   }
}

As @Gavin commented, double-tap on a button is an unusual gesture. On the iPhone OS double-tap is mostly used for zoomable views to zoom into/out of a region of focus. It may be unintuitive for the users if you make the gesture to perform other actions.

Swift 3:

button.addTarget(self, action: #selector(multipleTap(_:event:)), for: UIControlEvents.touchDownRepeat)

And then:

func multipleTap(_ sender: UIButton, event: UIEvent) {
    let touch: UITouch = event.allTouches!.first!
    if (touch.tapCount == 2) {
        // do action.
    }
}
Anh Pham
  • 2,108
  • 9
  • 18
  • 29
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • 1
    Thanks, this is a clean solution – Aitul Oct 15 '12 at 15:06
  • This could be useful for preventing unwanted double taps. For example if you're making a request to a server. – johnnymire May 08 '14 at 18:15
  • @johnnymire: You could as well immediately disable the button after the first click. – kennytm May 08 '14 at 19:11
  • Thanks for the solution. I tried it in swift, but I get error: Value of type 'Set?' has no member ‘anyObject’, and I don’t know how to fix this, any suggestions? Many Thanks! This is what I tried: var button: UIButton = button.addTarget(self, action: "multipleTap:withEvent:", forControlEvents: .TouchDownRepeat) ... @IBAction func multipleTap(sender: AnyObject, withEvent event: UIEvent) { var touch: UITouch = event.allTouches().anyObject() if touch.tapCount == 2 { // do action. } } – theMouse Nov 26 '15 at 23:44
  • @theMouse: See http://stackoverflow.com/questions/29584365/setnsobject-does-not-have-a-member-named-anyobject-xcode-6-3. – kennytm Nov 27 '15 at 02:39
  • @kennytm. I took the liberty of typing in the latest swift syntax. as always feel free to edit, unwind etc, cheers – Fattie Feb 24 '17 at 20:42
  • @kennytm, nice solution.. still working on iOS13.7... +1 for you. – Vatsal Shukla Feb 24 '22 at 13:35
2

If you are working with swift 5, @kennytm's solution won't work. So you can write an objective-c/swift function and add it as gesture with number of desired taps.

let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
tap.numberOfTapsRequired = 2
btn.addGestureRecognizer(tap)

and then

@objc func doubleTapped() {
    // your desired behaviour.
}

Here button can be tapped any number of times and it will show as tapped. But the above function won't execute until button tapped for required number of times.

Wimukthi Rajapaksha
  • 961
  • 1
  • 11
  • 23
1
[button addTarget:self action:@selector(button_TouchDown:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(button_TouchDownRepeat:withEvent:) forControlEvents:UIControlEventTouchDownRepeat];

-(void)button_one_tap:(UIButton*) button
{
    NSLog(@"button_one_tap");
}
-(void)button_double_tap:(UIButton*) button
{
    NSLog(@"button_double_tap");

}

-(void)button_TouchDown:(UIButton*) button
{
    NSLog(@"button_TouchDown");
    [self performSelector:@selector(button_one_tap:) withObject:button afterDelay:0.3 /*NSEvent.doubleClickInterval maybe too long*/];
}
-(void)button_TouchDownRepeat:(UIButton*) button withEvent:(UIEvent*)event {
    NSLog(@"button_TouchDownRepeat");

    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(button_one_tap:) object:button];

    UITouch* touch = [[event allTouches] anyObject];
    //NSLog(@"touch.tapCount = %ld", touch.tapCount);
    if (touch.tapCount == 2) {
        // do action.
        [self button_double_tap:button];
    }
}
user1105951
  • 2,259
  • 2
  • 34
  • 55
0

try to use this for the button event

UIControlEventTouchDownRepeat
itsji10dra
  • 4,603
  • 3
  • 39
  • 59
mohammad alabid
  • 444
  • 7
  • 21
-1
@IBOutlet weak var button: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()

    button.addTarget(self, action: "didTap:", forControlEvents: .TouchUpInside)
    button.addTarget(self, action: "didDoubleTap:", forControlEvents: .TouchDownRepeat)

}

var ignoreTap = false
func didTap(sender: UIButton) {
    if ignoreTap {
        ignoreTap = false
        print("ignoretap", sender)
        return
    }
    print("didTap", sender)
}

func didDoubleTap(sender: UIButton) {
    ignoreTap = true
    print("didDoubleTap", sender)
}
Yasmin Tiomkin
  • 282
  • 1
  • 5
  • 14