2015-04-04 7 views
3

У меня есть 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 появляется довольно поздно, создавая ощущение, что приложение отстает.

+0

Нет, вам нужно будет обрабатывать краны непосредственно, чтобы изменить время – Wain

+0

Как я могу это сделать? Это «лучшая практика»? – Nico

+0

Не тривиально в ячейке, возможно, вы бы использовали пользовательский подзаголовок, который реализовал методы сенсорного события. Или измените свой пользовательский интерфейс, чтобы не использовать двойной контакт – Wain

ответ

5

Я нашел ответ на этот link

Свифта версия:

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) 
    } 
+0

Не забудьте добавить 'import UIKit.UIGestureRecognizerSubclass' в файл, определяющий подкласс' UITapGestureRecognizer'. (из http://stackoverflow.com/a/26557518/341954) Иначе вы получите ошибку сборки: _ «Метод не отменяет какой-либо метод из его суперкласса» _. – PDK

1

на будущее, полное осуществление Говарда Ян, вот ссылки: 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) 
    } 
} 
+0

Хотя эта ссылка может ответить на вопрос, лучше включить основные части ответа здесь и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. –

0

Полная реализация Markus's Swift 3 версии eladleb's оригинального решения.


Создание подкласса файлу 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<UITouch>, 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 только DoubleTap должен быть типа UIShortTapGestureRecognizer & 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) 
} 
Смежные вопросы