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 } }
请注意,这是对UITap
replace。 所以在像…
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") }