检测单元格内 UILabel 上的点击

Detecting a tap on UILabel inside a cell

我在标签上有一个 UITapGestureRecognizer:

cell.label.userInteractionEnabled = true
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.labelTapped))
cell.label.addGestureRecognizer(gestureRecognizer)

我希望它在用户点击时更改文本。在 Whosebug 上寻找答案数小时后,我已经到了可以更改标签文本的地步。但它也会更改其他单元格标签上的文本。这是我实现的:

 func labelTapped(recognizer: UIGestureRecognizer){
        print("Label tapped.")

        let position: CGPoint =  recognizer.locationInView(self.tableView)
        let indexPath: NSIndexPath = self.tableView.indexPathForRowAtPoint(position)!
        let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! DataTableViewCell
        
        cell.label.text = "Test."
    }

帮我想办法。

电池可重复使用。这意味着当您更改单元格上的值时,它会更改并在该特定单元格标识符的所有重复使用中保持更改,直到您将其更改回来。

要解决您的问题,您可以在 cellForRowAtIndexPath 中设置 "placeholder"/DefaultText 文本,或者如果您 子类化 您的单元格,您可以设置 defaultText/placeholder 在 prepareForReuse 方法中。

你可以试试这个方法:

func labelTapped(recognizer: UITapGestureRecognizer){
    let dataCell: DataTableViewCell =  recognizer.view as! DataTableViewCell
    let indexPath = tableView.indexPath(for: dataCell)
    data[(indexPath?.row)!] = "changed value "
    self.tableView.reloadData()
}

我建议像 Sneak 已经提到的那样更改数据源。然后您可以在指定的 IndexPaths 重新加载您的 tableView 以获得所需的结果:

func handleLabelTap(sender: UIGestureRecognizer) {
    // Get references
    guard let label = sender.view as? UILabel else {
        print("Error not a label")
        return
    }
    let position = sender.location(in: self.tableView)
    guard let index = self.tableView.indexPathForRow(at: position) else { 
        print("Error label not in tableView")
        return
     }

    // Notify TableView of pending updates
    self.tableView.beginUpdates()
    defer { self.tableView.endUpdates() }

    // Alter Datasource
    self.data[index.row] = "Changed Value"
    self.tableView.reloadRows(at: [index], with: .automatic)
}

其中 self.data 是一个字符串数组,代表您的数据源。

编辑:Swift 评论中建议的 2.3 版本。

func handleLabelTap(sender: UIGestureRecognizer) {
    // Get references
    guard let label = sender.view as? UILabel else {
        print("Error not a label")
        return
    } 
    let position = sender.locationInView(self.tableView) 
    guard let index = self.tableView.indexPathForRowAtPoint(position) else { 
        print("Error label not in tableView")
        return
    } 

    // Notify TableView of pending updates
    self.tableView.beginUpdates() 
    defer { self.tableView.endUpdates() } 

    // Alter DataSource
    self.data[index.row] = "Changed Value" 
    self.tableView.reloadRowsAtIndexPaths([index], withRowAnimation: .Automatic)
}