在Swift 3中单击和双击UITableViewCell

bza*_*adm 2 uitableview uitapgesturerecognizer swift swift3

我在TableViewCell上有故事板segue,我用它在单击单击didSelectRowAt方法中转移到另一个VC .现在我做了双击TapGestureRecognizer以处理细胞上的轻微敲击.问题是,单击时,segue正在执行,双击不起作用.单击单元格,双击可正常工作.到目前为止我的代码可能以某种方式解决这个问题吗?或者我需要删除segue并单独处理单击和双击.谢谢你的任何建议

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
    doubleTap.numberOfTapsRequired = 2
    view.addGestureRecognizer(doubleTap)
}

func handleDoubleTap(recognizer: UIGestureRecognizer) {
    let p = recognizer.location(in: tableView)

    let indexPath = tableView.indexPathForRow(at: p)

    if let _ = indexPath {
        tableView.deselectRow(at: indexPath!, animated: true)
        update(index: (indexPath?.row)!, isFinished: true)
    }

    print ("doubke")
}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "showSingleTask") {
        if let indexPath = tableView.indexPathForSelectedRow {
            let nav = segue.destination as! UINavigationController
            let destinationVC = nav.topViewController as! ShowTaskVC
            destinationVC.singleTask = tasks[indexPath.row]
        }
    }
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    tableView.deselectRow(at: indexPath as IndexPath, animated: true)
    self.selectedTask = tasks[indexPath.row]
}
Run Code Online (Sandbox Code Playgroud)

Vas*_*huk 9

细节

xCode 8.3,Swift 3.1

检测TableViewCell上的双击和单击

ViewController.swift

protocol MultiTappableDelegate: class {
    func singleTapDetected(in view: MultiTappable)
    func doubleTapDetected(in view: MultiTappable)
}

class ThreadSafeValue<T> {
    private var _value: T
    private lazy var semaphore = DispatchSemaphore(value: 1)
    init(value: T) { _value = value }
    var value: T {
        get {
            semaphore.signal(); defer { semaphore.wait() }
            return _value
        }
        set(value) {
            semaphore.signal(); defer { semaphore.wait() }
            _value = value
        }
    }
}

protocol MultiTappable: UIView {
    var multiTapDelegate: MultiTappableDelegate? { get set }
    var tapCounter: ThreadSafeValue<Int> { get set }
}

extension MultiTappable {
    func initMultiTap() {
        if let delegate = self as? MultiTappableDelegate { multiTapDelegate = delegate }
        let tap = UITapGestureRecognizer(target: self, action: #selector(UIView.multitapActionHandler))
        addGestureRecognizer(tap)
    }

    func multitapAction() {
        if tapCounter.value == 0 {
            DispatchQueue.global(qos: .utility).async {
                usleep(250_000)
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    if self.tapCounter.value > 1 {
                        self.multiTapDelegate?.doubleTapDetected(in: self)
                    } else {
                        self.multiTapDelegate?.singleTapDetected(in: self)
                    }
                    self.tapCounter.value = 0
                }
            }
        }
        tapCounter.value += 1
    }
}

private extension UIView {
    @objc func multitapActionHandler() {
        if let tappable = self as? MultiTappable { tappable.multitapAction() }
    }
}
Run Code Online (Sandbox Code Playgroud)

TableViewCell.swift

class MyView: UIView, MultiTappable {
    weak var multiTapDelegate: MultiTappableDelegate?
    lazy var tapCounter = ThreadSafeValue(value: 0)
    override func awakeFromNib() {
        super.awakeFromNib()
        initMultiTap()
    }
}
Run Code Online (Sandbox Code Playgroud)

TableViewCellDelegate.swift

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
    }
}

extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int { return 1 }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
        cell.label.text = "\(indexPath)"
        cell.delegate = self
        return cell
    }
}

extension ViewController: TableViewCellDelegate {
    func singleTapDetected(in cell: TableViewCell)  {
        if let indexPath = tableView.indexPath(for: cell) { print("singleTap \(indexPath) ") }
    }
    func doubleTapDetected(in cell: TableViewCell) {
        if let indexPath = tableView.indexPath(for: cell) { print("doubleTap \(indexPath) ") }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述