Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITapGestureRecognizer - make it work on touch down, not touch up?

What I'm using the tap event for is very time-sensitive, so I'm curious if it's possible to make UITapGestureRecognizer activate when the user simply touches down, rather than requiring them to touch up as well?

like image 479
user212541 Avatar asked Mar 26 '13 02:03

user212541


People also ask

What is UIGestureRecognizer?

UIGestureRecognizer tracks the touch behavior on-screen interpreted by the user such as tap, pinch, rotate, swipe, pan, and long press and acts on the recognition based on the action method written. With the introduction of UIGestureRecognizer, it definitely will save you more time from writing additional code.

How do I add tap gestures in swift 5?

Adding a Tap Gesture Recognizer in Interface Builder You don't need to switch between the code editor and Interface Builder. Open Main. storyboard and drag a tap gesture recognizer from the Object Library and drop it onto the view we added earlier. The tap gesture recognizer appears in the Document Outline on the left.

How do you use UILongPressGestureRecognizer?

UILongPressGestureRecognizer is a concrete subclass of UIGestureRecognizer . The user must press one or more fingers on a view and hold them there for a minimum period of time before the action triggers.


2 Answers

Use a UILongPressGestureRecognizer and set its minimumPressDuration to 0. It will act like a touch down during the UIGestureRecognizerStateBegan state.

For Swift 4+

func setupTap() {     let touchDown = UILongPressGestureRecognizer(target:self, action: #selector(didTouchDown))     touchDown.minimumPressDuration = 0     view.addGestureRecognizer(touchDown) }  @objc func didTouchDown(gesture: UILongPressGestureRecognizer) {     if gesture.state == .began {         doSomething()     } } 

For Objective-C

-(void)setupLongPress {    self.longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPress:)];    self.longPress.minimumPressDuration = 0;    [self.view addGestureRecognizer:self.longPress]; }  -(void)didLongPress:(UILongPressGestureRecognizer *)gesture {    if (gesture.state == UIGestureRecognizerStateBegan){       [self doSomething];    } } 
like image 99
Rob Caraway Avatar answered Sep 28 '22 04:09

Rob Caraway


Create your custom TouchDownGestureRecognizer subclass and implement gesture in touchesBegan:

TouchDownGestureRecognizer.h

#import <UIKit/UIKit.h>  @interface TouchDownGestureRecognizer : UIGestureRecognizer  @end 

TouchDownGestureRecognizer.m

#import "TouchDownGestureRecognizer.h" #import <UIKit/UIGestureRecognizerSubclass.h>  @implementation TouchDownGestureRecognizer -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{     if (self.state == UIGestureRecognizerStatePossible) {         self.state = UIGestureRecognizerStateRecognized;     } }  -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{     self.state = UIGestureRecognizerStateFailed; }  -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{     self.state = UIGestureRecognizerStateFailed; }   @end 

implementation:

#import "TouchDownGestureRecognizer.h"     TouchDownGestureRecognizer *touchDown = [[TouchDownGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouchDown:)];     [yourView addGestureRecognizer:touchDown];  -(void)handleTouchDown:(TouchDownGestureRecognizer *)touchDown{     NSLog(@"Down"); } 

Swift implementation:

import UIKit import UIKit.UIGestureRecognizerSubclass  class TouchDownGestureRecognizer: UIGestureRecognizer {     override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)     {         if self.state == .Possible         {             self.state = .Recognized         }     }      override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent)     {         self.state = .Failed     }      override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent)     {         self.state = .Failed     } } 

Here is the Swift syntax for 2017 to paste:

import UIKit.UIGestureRecognizerSubclass  class SingleTouchDownGestureRecognizer: UIGestureRecognizer {     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {         if self.state == .possible {             self.state = .recognized         }     }     override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {         self.state = .failed     }     override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {         self.state = .failed     } } 

Note that this is a drop-in replacement for UITap. So in code like...

func add(tap v:UIView, _ action:Selector) {     let t = UITapGestureRecognizer(target: self, action: action)     v.addGestureRecognizer(t) } 

you can safely swap to....

func add(hairtriggerTap v:UIView, _ action:Selector) {     let t = SingleTouchDownGestureRecognizer(target: self, action: action)     v.addGestureRecognizer(t) } 

Testing shows it will not be called more than once. It works as a drop-in replacement; you can just swap between the two calls.

like image 25
LE SANG Avatar answered Sep 28 '22 06:09

LE SANG