Search code examples
iosswiftuitableviewuitapgesturerecognizer

Get label text from tapped cell with UITapGestureRecognizer


I want to edit label text on tap of the cell label (not didSelectRowAt). Tapped label function (toDoItemLabelTapped) shows nil.

Though UITapGestureRecognizer works well, it doesn't pass label text.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as!  ToDoItemsCell

    cell.delegate = self

    cell.textField.delegate = self
    cell.textField.isHidden = true
    cell.toDoItemLabel.isUserInteractionEnabled = true

    let aSelector : Selector = Selector(("toDoItemLabelTapped"))
    var tapGesture = UITapGestureRecognizer(target: self, action: aSelector)

    tapGesture.numberOfTapsRequired = 1
    cell.addGestureRecognizer(tapGesture)
    tapGesture.delegate = self as? UIGestureRecognizerDelegate
    tapGesture = UITapGestureRecognizer(target: self, action: aSelector)

    return cell
}

And here is the function:

var customTableViewController = ToDoItemsCell()

@objc func toDoItemLabelTapped() {
    print(customTableViewController.toDoItemLabel.text)
}

The error is the following:

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

How to make the tap gesture pass the cell's label text?


Solution

  • The problem is with your customTableViewController variable. It's referring to a useless cell that's not ever in the table view. Get rid of it. It's not necessary.

    Get the cell from the tap gesture. A tap gesture has a view property. Since you add the tap gesture to the cell, its view property will be the cell.

    @objc func toDoItemLabelTapped(_ gesture: UITapGestureRecognizer) {
        let cell = gesture.view as! ToDoItemsCell
        print(cell.toDoItemLabel.text)
    }
    

    You also need to fix the selector in cellForRowAt. Get rid of the aSelector variable.

    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toDoItemLabelTapped))
    

    Unless you have actually implement the gesture delegate methods for some reason, get rid of the line:

    tapGesture.delegate = self as? UIGestureRecognizerDelegate
    

    Also remove the extraneous line:

    tapGesture = UITapGestureRecognizer(target: self, action: aSelector)
    

    Also note that cells are reused so you are adding more and more tap gestures to each cell as the user scrolls. You may want to avoid adding more than one tap gesture to any cell.