UITapGestureRecognizer 中标记问题的说明

Explaination to tag issue in 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 returns 0 中制作打印语句作为标记,无论我是点击单元格 0 还是单元格 1,但是 cellForRowAt 中的打印语句打印正确的 indexPath.row 整数,0 和 1?我知道我可以使用 didSelectRowAt,但我想我只是变得固执了。

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

  • 更新答案

发生这种情况是因为您在向单元格添加手势之前设置了标签。在这种情况下,tapGestureRecognizer.view 此时为空。向单元格添加手势后只需做一件事设置标签。

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

您不应使用 cellForRow 将 tapGesture 添加到单元格中...因为单元格得到重用,所以相同的手势将应用于多个单元格。因此,与其将其添加到行的单元格中,不如将它们添加到 CustomTableViewCell class 中的自定义单元格 init() 方法中,因此它只添加一次......您可以将 Tag 设置为那个cellForRow 方法中的手势不会导致任何问题...

您需要在 UITapGestureRecognizer 中设置视图标签的值 class。只需在初始化 '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))")
}