How to add gesture to UITableViewCell?
Solution 1
To add gesture to UITableViewCell, you can follow the steps below:
First, add gesture recognizer to UITableView
tapGesture = UITapGestureRecognizer(target: self, action: #selector(tableViewController.tapEdit(_:)))
tableView.addGestureRecognizer(tapGesture!)
tapGesture!.delegate = self
Then, define the selector. Use recognizer.locationInView
to locate the cell you tap in tableView. And you can access the data in your dataSource by tapIndexPath
, which is the indexPath of the cell the user tapped.
func tapEdit(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.Ended {
let tapLocation = recognizer.locationInView(self.tableView)
if let tapIndexPath = self.tableView.indexPathForRowAtPoint(tapLocation) {
if let tappedCell = self.tableView.cellForRowAtIndexPath(tapIndexPath) as? MyTableViewCell {
//do what you want to cell here
}
}
}
}
It is possible to add gesture directly to TableView cell and access the datasource in viewController, You need to set up a delegate:
In your custom cell:
import UIKit
class MyTableViewCell: UITableViewCell {
var delegate: myTableDelegate?
override func awakeFromNib() {
super.awakeFromNib()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyTableViewCell.tapEdit(_:)))
addGestureRecognizer(tapGesture)
//tapGesture.delegate = ViewController()
}
func tapEdit(sender: UITapGestureRecognizer) {
delegate?.myTableDelegate()
}
}
protocol myTableDelegate {
func myTableDelegate()
}
In your viewController:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate, myTableDelegate {
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 35
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? MyTableViewCell
cell?.delegate = self
return cell!
}
func myTableDelegate() {
print("tapped")
//modify your datasource here
}
}
However, this method could cause problems, see UIGestureRecognizer and UITableViewCell issue. In this case, when the swipe gesture successes, the selector get called twice for some reason. I can't say the second method is a bad one as I haven't found any direct evidence yet, but after searching through Google, it seems like the first method is the standard way.
Solution 2
You don't need to add gesture recognizer to achieve what you are doing.
- Use the
UITableViewDelegate
methodtableView:didSelectRowAtIndexPath:
to detect which row is tapped (this is what exactly yourtapGesture
is going to do) and then do your desired processing. - If you don't like the gray indication when you select cell, type this in your
tableView:didEndDisplayingCell:forRowAtIndexPath:
just before returning the cell:
cell?.selectionStyle = .None
Solution 3
Adding gesture in awakeFromNib method seems much more easier and works fine.
class TestCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
let panGesture = UIPanGestureRecognizer(target: self,
action: #selector(gestureAction))
addGestureRecognizer(panGesture)
}
@objc func gestureAction() {
print("gesture action")
}
}
Fate Riddle
Updated on April 06, 2020Comments
-
Fate Riddle about 4 years
I want to add a tap gesture to every cell in a
UITableView
that edits the content in it. The two ways to add a gesture are in code or through storyboard. I tried both and they failed.Can I add a gesture to every cell in table with storyboard drag and drop? It seems to only add gesture to the first cell. Adding gesture in code, I wrote something like,
addGestureRecognizer(UITapGestureRecognizer(target: self,action:#selector(MyTableViewCell.tapEdit(_:))))
or
addGestureRecognizer(UITapGestureRecognizer(target: self, action:"tapEdit:"))
both work. But I'd like to let the
UITableViewController
handle this gesture because it does something with the datasource. How do I write my target and action?EDIT:
addGestureRecognizer(UITapGestureRecognizer(target: MasterTableViewController.self, action:#selector(MasterTableViewController.newTapEdit(_:)))
it induce an error said, unrecognized selector sent to class 0x106e674e0...
-
Fate Riddle almost 8 yearsIt seems natural to add gesture to tableViewCell rather than tableView then specify which in code. And for more complicated gestures like pan, writing condition checks if a pan starts/stays/ends in a cell and handle other cases can be painful for me. I'd like to add gesture to tableviewcell, writing code in tableviewcell.swift. is it possible? And can you answer my second question as how do I write the target & selector of UITapGestureRecognizer(target, action)
-
Fate Riddle almost 8 yearsTap is just one example, I'd love to do all sorts of gesture on each cell.
-
Rohan Sanap almost 8 yearsDo u have a custom class for the cell?
-
Rohan Sanap almost 8 yearsIf yes the add the gesture recognizer in
awakeFromNib
method in the custom cell class -
Fate Riddle almost 8 yearsI did exactly that, but I don't know how to write a UITapGestureRecognizer that uses function in TableViewController. If the code is in awakeFromNib in myTableViewCell.swift
-
ilovecomputer almost 8 yearsTarget & selector
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyTableViewCell.tapEdit(_:)))
-
Fate Riddle almost 8 yearslet tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyTableViewCell.tapEdit(_:))) is working. But in my case, the gesture interacts with datasource, so I'd like the target be UITableViewController, and uses one of the function in tere(which can alter datasource), How to do that?
-
Fate Riddle almost 8 yearsThanks, it works. Out of curiosity, target can only be self (or something belongs to the class)?
-
ilovecomputer almost 8 years@FateRiddle No. target is an object that is a recipient of action messages sent by the receiver when the represented gesture occurs. You may call this method multiple times to specify multiple target-action pairs. However, if you request to add a target-action pair that has already been added, then the request is ignored. “self” here is your custom cell
-
Fate Riddle almost 8 yearsIt seems I cannot call a
UITableViewController
as target if the codeUITapGestureRecognizer(target: MasterViewController ...)
is inMyUITableViewCell.swift
. Error occurs. @luiyezheng -
Mamta over 7 yearsPlease could someone tell me how to identify which cell was clicked in this method : func myTableDelegate() { print("tapped") }
-
Vlad Bruno about 3 yearsInstance member 'addGestureRecognizer' cannot be used on type 'TestViewCell'