Uzy
Uzy

Reputation: 1

How to not respond to didSelectRowAt when adding single and double click UITapGestureRecognizer on UITableViewCell

I added UITapGestureRecognizer for single and double clicks on UITableViewCell, and let the single click gesture be responded to when the double click gesture fails, but I don't want the tableView's didSelected to be responded to. Is there any way to handle this in the TableViewCell class?

class ViewController: UIViewController {
    
    let dataSource = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    
    lazy var tableView: UITableView = {
        let view = UITableView(frame: CGRectZero)
        view.dataSource = self
        view.delegate = self
        view.register(TableViewCell.self, forCellReuseIdentifier: TableViewCell.description())
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.view.addSubview(tableView);
        tableView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
    }
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.description(), for: indexPath) as? TableViewCell {
            return cell;
        }
        return UITableViewCell()
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        40
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         
    }
}

class TableViewCell: UITableViewCell {
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(tap))
        singleTapGesture.cancelsTouchesInView = false;
        addGestureRecognizer(singleTapGesture)
        
        let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(doubleTap))
        doubleTapGesture.numberOfTapsRequired = 2
        addGestureRecognizer(doubleTapGesture)
       
        singleTapGesture.require(toFail: doubleTapGesture)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc func tap() {
        
    }
    
    @objc func doubleTap() {
        
    }
}

I want only tap and doubleTap to be called in case of single and double click, but didSelectRowAt is not called

Upvotes: 0

Views: 49

Answers (1)

DonMag
DonMag

Reputation: 77423

It's not entirely clear what you mean when you say you don't want "didSelected to be responded to" ...

If you don't have a didSelectRowAt function, the default is to do nothing, so it's "not responding" to it.

If you don't want the cell to highlight, in cellForRowAt you can set:

if let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.description(), for: indexPath) as? TableViewCell {
    cell.selectionStyle = .none
    return cell;
}

The table view will still internally track that a row is selected, but there will be no visual indication, and if your code does not implement didSelectRowAt there won't be a "response."

If you want to prevent the table view from tracking the selected row, you can implement shouldHighlightRowAt:

func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    return false
}

Now, you don't need cell.selectionStyle = .none and didSelectRowAt will never be called.

Upvotes: 0

Related Questions