Foefirelord Foefirelord - 9 days ago 4
Swift Question

Is there any way to setup gesture recognizers for repeating UI elements such as UITableViewCells?

I'm developing an iOS app with a UITableView that requires a swipe gesture to perform a certain action for any cell (row) in the table.

When I initially implemented the IBAction for the gesture in my view controller (the one with the UITableView in it), I wasn't even able to run the app, as Xcode informed me with an error that it doesn't allow attaching gestures to repeating interface elements (the cell being a repeating element, since a new one is generated each time one is needed via dequeueing a reusable cell).

So I then proceeded to place the IBAction for the swipe gesture inside my custom table cell class instead, at which point I no longer receive the error that prevents me from building/running, but am still receiving a warning in the debug console while running the app, which states that since iOS9, the system now enforces the prohibition of gestures attached to repeating elements (in this case, my table cell).

If anyone has insight into gesture recognizers, I'd appreciate it if you could help me figure out the following questions.


  1. Should I take this warning at face value and assume that I'm not allowed to attach any gestures to table cells at all?

  2. In either case, is there some other way to attach a gesture to repeating elements like prototype table cells and avoid any kind of warnings/prohibitions?


Answer

You should put the swipe in your viewcontroller and get a cell through Swipe IBAction with the code below. Once you've done that, you can do what you want: cell.do_something or cell.element.do_something

You get the cell with the position of swipe, like:

Objective C:

CGPoint location = [sender locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

Swift:

let location : CGPoint = sender.locationInView(self.tableView)
let indexPath : NSIndexPath = tableView.indexPathForRowAtPoint(location)
let cell : UITableViewCell = tableView(tableView, cellForRowAtIndexPath: indexPath)