How can I add a Gesture Recognizer to a UIImageView
in a table cell? I want it so that if a user taps an image in the cell, the image will change and the data model will update.
I know this needs to be set up in the UITableViewController
. My code currently can execute a command if anywhere in the cell is tapped, but I would like it to execute only if the image is tapped, not anywhere in the cell.
I setup up the gesture recognizer in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Load sample data
loadSampleHabits()
// Initialize tap gesture recognizer
var recognizer = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:)))
// Add gesture recognizer to the view
self.tableView.addGestureRecognizer(recognizer)
And this is the function
//action method for gesture recognizer
func tapEdit(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.ended {
let tapLocation = recognizer.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) as? HabitTableViewCell {
print("Row Selected")
}
}
}
As a secondary question, are there any conflicts if I want to add a gesture recognizer to the cell and the image view within the cell?
You are adding gesture recognizer on your tableview instead of imageView as you required. Yo need to move your code from viewDidLoad to cellForRowAtIndexPath
and add gesture to imageView in each cell while configuing your cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
var recognizer = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:)))
// Add gesture recognizer to your image view
cell.yourimageview.addGestureRecognizer(recognizer)
}
Note: Do make sure to enable userinteraction
of your image view
cell.yourimageview.userInteractionEnabled = YES;
For your requirement I will suggest using UILongPressGestureRecognizer as it has less chances of conflict in gesture and didselect. Yo can add UILongPressGestureRecognizer in viewDidLoad and access it as per your requirement.
let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.handleLongPress(_:)))
lpgr.minimumPressDuration = 1
tableView.addGestureRecognizer(lpgr)
Define method as
func handleLongPress(_ gesture: UILongPressGestureRecognizer){
if gesture.state != .began { return }
let tapLocation = gesture.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) as? HabitTableViewCell {
print("Row Selected")
}
}
You can try removing if recognizer.state == UIGestureRecognizerState.ended
condition from your method.
UITapGestureRecognizer is a discrete gesture, and as such, your event handler is called only once when the gesture was recognized. You don't have to check the state at all. Certainly you won't receive a call for the state of .Began. For more info consider @Rob ans here.
For my suggestion you have to use UIButton
in cell, for performance
improvements,
UIButtons
Specially designed for this and have been extensively optimized by Apple for touches.
If you want image in cell you can use UIButton
with Image inside.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With