如何通过双击加速识别单个水龙头?

我有一个带行的UITableView,我添加了单击手势和双击手势:

let doubleTap = UITapGestureRecognizer(target: self, action: "doubleTap:") doubleTap.numberOfTapsRequired = 2 doubleTap.numberOfTouchesRequired = 1 tableView.addGestureRecognizer(doubleTap) let singleTap = UITapGestureRecognizer(target: self, action: "singleTap:") singleTap.numberOfTapsRequired = 1 singleTap.numberOfTouchesRequired = 1 singleTap.requireGestureRecognizerToFail(doubleTap) tableView.addGestureRecognizer(singleTap) 

有没有办法缩短第一次点击的时间和手势识别器识别出它是单击而不是双击的时间。

我问这个是因为当我点击一下时,新的viewController显得很晚,给人一种应用滞后的感觉。

我在这个链接上找到了答案

快速版本:

 class UIShortTapGestureRecognizer: UITapGestureRecognizer { let tapMaxDelay: Double = 0.3 override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) { super.touchesBegan(touches, withEvent: event) delay(tapMaxDelay) { // Enough time has passed and the gesture was not recognized -> It has failed. if self.state != UIGestureRecognizerState.Ended { self.state = UIGestureRecognizerState.Failed } } } } 

delay(delay: Double, closure:()->())

 class func delay(delay:Double, closure:()->()) { dispatch_after(dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), closure) } 

对于未来,由Howard Yang全面实施,这里的链接: https : //github.com/oney/SingleDoubleTapGestureRecognizer

  let tap = SingleDoubleTapGestureRecognizer(target: self, singleAction: Selector("singleTap"), doubleAction: Selector("doubleTap")) tap.duration = 0.8 view.addGestureRecognizer(tap) 

https://github.com/oney/SingleDoubleTapGestureRecognizer/blob/master/Pod/Classes/SingleDoubleTapGestureRecognizer.swift

 // // SingleDoubleTapGestureRecognizer.swift // SingleDoubleTapGestureRecognizer // // Created by Howard Yang on 08/22/2015. // Copyright (c) 2015 Howard Yang. All rights reserved. // import UIKit public class SingleDoubleTapGestureRecognizer: UITapGestureRecognizer { var targetDelegate: SingleDoubleTapGestureRecognizerDelegate public var duration: CFTimeInterval = 0.3 { didSet { self.targetDelegate.duration = duration } } public init(target: AnyObject, singleAction: Selector, doubleAction: Selector) { targetDelegate = SingleDoubleTapGestureRecognizerDelegate(target: target, singleAction: singleAction, doubleAction: doubleAction) super.init(target: targetDelegate, action: Selector("fakeAction:")) numberOfTapsRequired = 1 } } class SingleDoubleTapGestureRecognizerDelegate: NSObject { var target: AnyObject var singleAction: Selector var doubleAction: Selector var duration: CFTimeInterval = 0.3 var tapCount = 0 init(target: AnyObject, singleAction: Selector, doubleAction: Selector) { self.target = target self.singleAction = singleAction self.doubleAction = doubleAction } func fakeAction(g: UITapGestureRecognizer) { tapCount = tapCount + 1 if tapCount == 1 { delayHelper(duration, task: { if self.tapCount == 1 { NSThread.detachNewThreadSelector(self.singleAction, toTarget:self.target, withObject: g) } else if self.tapCount == 2 { NSThread.detachNewThreadSelector(self.doubleAction, toTarget:self.target, withObject: g) } self.tapCount = 0 }) } } typealias DelayTask = (cancel : Bool) -> () func delayHelper(time:NSTimeInterval, task:()->()) -> DelayTask? { func dispatch_later(block:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), block) } var closure: dispatch_block_t? = task var result: DelayTask? let delayedClosure: DelayTask = { cancel in if let internalClosure = closure { if (cancel == false) { dispatch_async(dispatch_get_main_queue(), internalClosure); } } closure = nil result = nil } result = delayedClosure dispatch_later { if let delayedClosure = result { delayedClosure(cancel: false) } } return result; } func cancel(task:DelayTask?) { task?(cancel: true) } } 

完全实现了Markus的 Swift 3版本的eladleb原始解决方案。


创建子类文件UIShortTapGestureRecogninzer

 import UIKit import UIKit.UIGestureRecognizerSubclass class UIShortTapGestureRecognizer: UITapGestureRecognizer { let tapMaxDelay: Double = 0.3 //anything below 0.3 may cause doubleTap to be inaccessible by many users override func touchesBegan(_ touches: Set, with event: UIEvent) { super.touchesBegan(touches, with: event) DispatchQueue.main.asyncAfter(deadline: .now() + tapMaxDelay) { [weak self] in if self?.state != UIGestureRecognizerState.recognized { self?.state = UIGestureRecognizerState.failed } } } } 

注意:添加UIGestureRecognizer只需要UIShortTapGestureRecognizer类型为UIShortTapGestureRecognizersingleTap.require(toFail: doubleTap)需要singleTap.require(toFail: doubleTap)

 func addBoth (views: UIView, selectorSingle: Selector, selectorDouble: Selector) { let doubleTap:UIShortTapGestureRecognizer = UIShortTapGestureRecognizer(target: self, action: selectorDouble) doubleTap.numberOfTapsRequired = 2 views.addGestureRecognizer(doubleTap) let singleTap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: selectorSingle) singleTap.numberOfTapsRequired = 1 singleTap.require(toFail: doubleTap) views.addGestureRecognizer(singleTap) } 

我宁愿建议使用canBePrevented(by :)函数,它会占用点击量来执行,并且除非第一个被识别/失败,否则不会运行双击手势识别器。 canBePrevented(由:)