UITapGestureRecognizer – 使它在触摸下工作,而不是触摸?

我使用tap事件的时间非常敏感,所以我很好奇,如果可以在用户简单触摸时激活UITapGestureRecognizer,而不是要求他们触摸,

创build自定义的TouchDownGestureRecognizer子类并在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 

执行:

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

快速实施:

 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 } } 

这里是粘贴2017年的Swift语法:

 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 } } 

请注意,这是对UITapreplace。 所以在像…

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

你可以安全地交换….

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

testing显示它不会被多次调用。 它作为一个直接替代品; 你可以在两个电话之间交换。

使用UILongPressGestureRecognizer并将其minimumPressDuration设置为0.在UIGestureRecognizerStateBegan状态期间,它将像触摸一样。

例:

 -(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]; } } 

Swift(没有子类)

这是一个类似于Rob Caraway的Objective-C答案的Swift版本。

这个想法是使用一个长按手势识别器与minimumPressDuration设置为零,而不是使用轻minimumPressDuration手势识别器。 这是因为长按手势识别器报告触摸开始事件,而轻击手势不触摸。

 import UIKit class ViewController: UIViewController { @IBOutlet weak var myView: UIView! override func viewDidLoad() { super.viewDidLoad() // Add "long" press gesture recognizer let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler)) tap.minimumPressDuration = 0 myView.addGestureRecognizer(tap) } // called by gesture recognizer func tapHandler(gesture: UITapGestureRecognizer) { // handle touch down and touch up events separately if gesture.state == .Began { // do something... } else if gesture.state == .Ended { // optional for touch up event catching // do something else... } } } 

这是另一个解决scheme。 创buildUIControl的子类。 你甚至可以在故事板中像UIView一样使用它,因为UIControl是UIView的子类。

 class TouchHandlingView: UIControl { } 

并addTarget:

 @IBOutlet weak var mainView: TouchHandlingView! ... mainView.addTarget(self, action: "startAction:", forControlEvents: .TouchDown) ... 

然后指定的动作将被称为像UIButton:

 func startAction(sender: AnyObject) { print("start") }