在Swift 3中对UITableViewCell进行单击和双击 [英] Single and double taps on UITableViewCell in Swift 3

查看:180
本文介绍了在Swift 3中对UITableViewCell进行单击和双击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在TableViewCell上有故事板segue,用于在单元格中单击didSelectRowAt方法将其转移到另一个VC.现在,我双击了TapGestureRecognizer来处理单元格上的麻烦点按.问题是在单击时,segue正在执行,而双击则不起作用.点按两次跳出单元格即可正常工作.到目前为止,是否有可能以某种方式解决此问题?或者我需要删除segue并分别处理单击和双击. 感谢您的任何建议

I have storyboard segue on TableViewCell, which I use for transfering to another VC on cell click in didSelectRowAt method. Now I made double tap TapGestureRecognizer to handle touble tap on cell. Problem is that on single tap, segue is performing and double tap is not working. Double tap works fine with clicking out of cell. Is possible to solve this somehow with my code so far? Or I need to delete segue and handle single tap and double tap separately. Thanks for any suggestions

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

推荐答案

详细信息

  • Xcode 10.2.1(10E1001),Swift 5
  • 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() }
        }
    }
    

    用法

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

    完整样本

    ViewController.swift

    ViewController.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) ") }
        }
    }
    

    TableViewCell.swift

    TableViewCell.swift

    import UIKit
    
    protocol TableViewCellDelegate: class {
        func singleTapDetected(in cell: TableViewCell)
        func doubleTapDetected(in cell: TableViewCell)
    }
    
    class TableViewCell: UITableViewCell, MultiTappable {
        weak var multiTapDelegate: MultiTappableDelegate?
        lazy var tapCounter = ThreadSafeValue(value: 0)
    
        @IBOutlet weak var label: UILabel!
        weak var delegate: TableViewCellDelegate?
    
        override func awakeFromNib() {
            super.awakeFromNib()
            initMultiTap()
        }
    }
    
    extension TableViewCell: MultiTappableDelegate {
        func singleTapDetected(in view: MultiTappable) { self.delegate?.singleTapDetected(in: self) }
        func doubleTapDetected(in view: MultiTappable) { self.delegate?.doubleTapDetected(in: self) }
    }
    

    Main.storyboard

    Main.storyboard

    <?xml version="1.0" encoding="UTF-8"?>
    <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="g2V-T0-sqD">
        <device id="retina4_7" orientation="portrait">
            <adaptation id="fullscreen"/>
        </device>
        <dependencies>
            <deployment identifier="iOS"/>
            <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
            <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
            <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
        </dependencies>
        <scenes>
            <!--View Controller-->
            <scene sceneID="tne-QT-ifu">
                <objects>
                    <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_43153530" customModuleProvider="target" sceneMemberID="viewController">
                        <layoutGuides>
                            <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                            <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                        </layoutGuides>
                        <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                            <subviews>
                                <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="fQm-mQ-a9u">
                                    <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                                    <prototypes>
                                        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="TableViewCell" id="nsF-ue-0bK" customClass="TableViewCell" customModule="stackoverflow_43153530" customModuleProvider="target">
                                            <rect key="frame" x="0.0" y="28" width="375" height="44"/>
                                            <autoresizingMask key="autoresizingMask"/>
                                            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nsF-ue-0bK" id="pT6-2N-oTC">
                                                <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                                                <autoresizingMask key="autoresizingMask"/>
                                                <subviews>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fEK-J3-oqH">
                                                        <rect key="frame" x="8" y="8" width="42" height="21"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                </subviews>
                                                <constraints>
                                                    <constraint firstItem="fEK-J3-oqH" firstAttribute="leading" secondItem="pT6-2N-oTC" secondAttribute="leadingMargin" id="Vfg-Ij-f6c"/>
                                                    <constraint firstItem="fEK-J3-oqH" firstAttribute="top" secondItem="pT6-2N-oTC" secondAttribute="topMargin" id="tc0-qJ-N1n"/>
                                                </constraints>
                                            </tableViewCellContentView>
                                            <connections>
                                                <outlet property="label" destination="fEK-J3-oqH" id="YBJ-tG-J5T"/>
                                            </connections>
                                        </tableViewCell>
                                    </prototypes>
                                </tableView>
                            </subviews>
                            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                            <constraints>
                                <constraint firstItem="fQm-mQ-a9u" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="8Vy-l8-jpB"/>
                                <constraint firstItem="fQm-mQ-a9u" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="Wwr-ox-Qbd"/>
                                <constraint firstItem="fQm-mQ-a9u" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="-64" id="xJR-Uk-rbj"/>
                                <constraint firstAttribute="trailing" secondItem="fQm-mQ-a9u" secondAttribute="trailing" id="zxs-ED-Whb"/>
                            </constraints>
                        </view>
                        <navigationItem key="navigationItem" id="pLJ-Bz-NIm"/>
                        <connections>
                            <outlet property="tableView" destination="fQm-mQ-a9u" id="DhZ-jj-zmB"/>
                        </connections>
                    </viewController>
                    <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
                </objects>
                <point key="canvasLocation" x="1079.2" y="137.18140929535232"/>
            </scene>
            <!--Navigation Controller-->
            <scene sceneID="w7e-Wj-oUR">
                <objects>
                    <navigationController automaticallyAdjustsScrollViewInsets="NO" id="g2V-T0-sqD" sceneMemberID="viewController">
                        <toolbarItems/>
                        <navigationBar key="navigationBar" contentMode="scaleToFill" id="7qG-8v-S0O">
                            <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                            <autoresizingMask key="autoresizingMask"/>
                        </navigationBar>
                        <nil name="viewControllers"/>
                        <connections>
                            <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="yqZ-pK-Yf3"/>
                        </connections>
                    </navigationController>
                    <placeholder placeholderIdentifier="IBFirstResponder" id="tnz-x0-vDN" userLabel="First Responder" sceneMemberID="firstResponder"/>
                </objects>
                <point key="canvasLocation" x="140" y="137.18140929535232"/>
            </scene>
        </scenes>
    </document>
    

    结果

    这篇关于在Swift 3中对UITableViewCell进行单击和双击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆