简体   繁体   中英

how to recognize label click on custom UITableViewCell - Swift 3

I have a custom UITableViewCell on which I have a Label , which needs to be made clickable depending on a certain condition. So I have added a TapGestureRecognizer on it. I have used protocols and delegates for the same. I want to pass a parameter along with performing a segue on click of this UILabel . I am able to perform this segue but cannot detect which cell's label was it.

I am new to this and have been stuck for a few hours. Any help would be appreciated. Please also tell me if there is another simpler way for the same result.

If it would be a button I could have added a target but I am really stuck now.

As @KrishnaCA says in their answer, if you want the whole label to be clickable it's probably better to use a button. If you need it to look different than a button, you can also place a transparent button (custom style with no image) on top of the label.

Whether you use a button or a label + tap gesture recognizer you still need to figure out which indexPath the user tapped on. You can put a tag in the button/label as Hamid suggests, but that's fragile. I prefer a different way. I've written an extension to UITableView that lets you figure out which cell owns a given view:

public extension UITableView {

  /// This method returns the indexPath of the cell that contains the specified view
  /// - parameter view: The view to find.
  /// - returns: The indexPath of the cell containing the view, or nil if it can't be found

  func indexPathForView(_ view: UIView) -> IndexPath? {
    let origin = view.bounds.origin
    let viewOrigin = self.convert(origin, from: view)
    let indexPath = self.indexPathForRow(at: viewOrigin)
    return indexPath
  }
}

If you add that extension to your project you can use code like below.

Gesture recognizer:

@objc func alertClicked(sender: UIGestureRecognizer){
  let view = sender.view
  let indexPath = tableView.indexPathForView(view)
  //Do whatever you need to do with the indexPath
}

or, for a button action:

@objc func buttonClicked(sender: UIButton) {
  let indexPath = tableView.indexPathForView(sender)
  //Do whatever you need to do with the indexPath 
} 

give each cell a unique tag and then:

 self.tag = x // x is a unique number
 label.isUserInteractionEnabled = true

let tapGesture = UITapGestureRecognizer(target: self, action:#selector(self.alertClicked(sender:)))
self.label.addGestureRecognizer(tapGesture)
tapGesture.delegate = self

and add this function to your CustomCell Class:

func alertClicked(sender: UITapGestureRecognizer){
    print(self.tag)// prints x

}

Personally I prefer to sub-class the TableViewCell and use delegate methods to send taps back to the TableView. You will need to provide and hold the indexPath in the TableViewCell and pass it back with the delegate method which technically breaks MVC but personally the code is much cleaner this way. I can post code if you are interested in this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM