说明UITapGestureRecognizer中的标签问题

问题描述

这对我来说不是一个大问题,我只是在努力了解正在发生的事情。其他宁愿如何使它按我希望的方式工作。

考虑以下任何标准UITableViewController的代码

var tapGestureRecognizer = UITapGestureRecognizer()

override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    guard let customCell = tableView.dequeueReusableCell(withIdentifier: customCellID) as? CustomTableViewCell else { return UITableViewCell() }
    
    if indexPath.row == 0 {

        print("Inside cellForRowAt: \(indexPath.row)")

        customCell.backgroundColor = .red
        
        tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(tagIndexPathRowMethod))
        tapGestureRecognizer.cancelstouchesInView = false
        tapGestureRecognizer.view?.tag = indexPath.row
        
        customCell.isUserInteractionEnabled = true
        customCell.addGestureRecognizer(tapGestureRecognizer)
        
        return customCell
        
    } else {

        print("Inside cellForRowAt: \(indexPath.row)")

        customCell.backgroundColor = .blue
        
        tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(tagIndexPathRowMethod))
        tapGestureRecognizer.cancelstouchesInView = false
        tapGestureRecognizer.view?.tag = indexPath.row
        
        customCell.isUserInteractionEnabled = true
        customCell.addGestureRecognizer(tapGestureRecognizer)
        
        return customCell
    }
}

@objc private func tagIndexPathRowMethod(sender: UITapGestureRecognizer) {
    print("Cell number tag: \(String(describing: sender.view?.tag))")
}

我已经尝试过将属性方法和单元格拆分为单独的代码,例如

var firstTapGestureRecognizer = UITapGestureRecognizer()
var secondTapGestureRecognizer = UITapGestureRecognizer()

等,但是标记仍然在两个单元格中仅打印0。

有人可以向我解释如何使tagIndexPathRowMethod中的print语句返回0作为标记,无论我点击单元格0还是单元格1,但是cellForRowAt内部的print语句打印正确的indexPath.row整数0和1?我知道我可以使用didSelectRowAt,但是我想我变得很固执。

(我很清楚我每次都违反DRY原则,但这只是一个教学示例。)

解决方法

  • 更新后的答案

之所以发生这种情况,是因为您在将手势添加到单元格之前先设置了标签。在这种情况下,tapGestureRecognizer.view当时为null。在单元格中添加手势后,只需做一件事即可设置标签。

   customCell.addGestureRecognizer(tapGestureRecognizer)
   
   tapGestureRecognizer.view?.tag = indexPath.row
,

您不应该使用cellForRow将tapGesture添加到单元格...随着单元格的重用,因此相同的手势将应用于多个单元格。因此,与其在行中的单元格中添加它,不如在init()类的情况下在自定义单元格CustomTableViewCell方法中添加它们,因此仅添加一次...您可以在{{ 1}}方法,不会引起任何问题...

,

您需要在UITapGestureRecognizer类中设置view标签的值。初始化“ customCell”后,只需在下面添加一行即可。

customCell.tag = indexPath.row

代码:

override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    guard let customCell = tableView.dequeueReusableCell(withIdentifier: customCellID) as? CustomTableViewCell else { return UITableViewCell() }
    customCell.tag = indexPath.row

    if indexPath.row == 0 {

        print("Inside cellForRowAt: \(indexPath.row)")

        customCell.backgroundColor = .red
        
        let tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(tagIndexPathRowMethod))
        tapGestureRecognizer.cancelsTouchesInView = false
        tapGestureRecognizer.view?.tag = indexPath.row
        
        customCell.isUserInteractionEnabled = true
        customCell.addGestureRecognizer(tapGestureRecognizer)
        
        return customCell
        
    } else {

        print("Inside cellForRowAt: \(indexPath.row)")

        customCell.backgroundColor = .blue
        
        let tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(tagIndexPathRowMethod))
        tapGestureRecognizer.cancelsTouchesInView = false
        tapGestureRecognizer.view?.tag = indexPath.row
        
        customCell.isUserInteractionEnabled = true
        customCell.addGestureRecognizer(tapGestureRecognizer)
        
        return customCell
    }
}

@objc private func tagIndexPathRowMethod(sender: UITapGestureRecognizer) {
    print("Cell number tag: \(String(describing: sender.view?.tag))")
}