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?
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.
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.
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.
Use a UILongPressGestureRecognizer and set its minimumPressDuration
to 0. It will act like a touch down during the UIGestureRecognizerStateBegan
state.
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() } }
-(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]; } }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With