I’m trying to implement a twitter iPhone app like interface. (Swipe to replace view in a tableviewcell with a custom view). I’m using Apple’s UISwipeGestureRecognizer to recognize the swipe and I’m getting the start location for that swipe using [recognizer locationInView:self.view]. This gives me a CGPoint and I’m using that with [tableView indexPathForRowAtPoint:location]. My problem with this is, my swipe always seems to get detected at one row above or below the actual row that I swiped in. Has anyone been experiencing the same issue?
EDIT: I should probably also mention that I’m using a custom tableview cell, and it’s height is more than the default view. I’m not sure if that makes any difference, I’m using heightForRowIndexAtPath: to return the height.
My code is –
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ModelObject *rowData = (ModelObject *)[tempArr objectAtIndex:indexPath.row];
if (rowData.isAlternateView) {
// Load alternateview
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[cell addGestureRecognizer:recognizer];
[recognizer release];
return cell;
}
else {
// Load the correct uitableviewcell
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[cell addGestureRecognizer:recognizer];
[recognizer release];
return cell;
}
}
-(void) handleSwipe:(UISwipeGestureRecognizer *) recognizer
{
NSLog(@"Swipe detected!");
CGPoint location = [recognizer locationInView:self.view];
NSIndexPath *selectedIndexPath = [tableView indexPathForRowAtPoint:location];
NSLog(@"Swipe detected at %d", selectedIndexPath.row);
ModelObject *rowData = (ModelObject *)[modelArr objectAtIndex:selectedIndexPath.row];
rowData.isAlternateView = YES;
for (int i=0; i<[tempArr count]; i++) {
if (i!=selectedIndexPath.row) {
ModelObject *rowToBeCleared = (ModelObject *) [modelArr objectAtIndex:i];
if ([rowToBeCleared isAlternateView]) {
[rowToBeCleared setIsAlternateView:NO];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:i inSection:0],nil] withRowAnimation:UITableViewRowAnimationLeft];
}
}
}
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:selectedIndexPath,nil] withRowAnimation:UITableViewRowAnimationRight];
}
First, rather than adding a gesture recognizer to each cell, I’d suggest adding just one gesture recognizer to the whole view that contains the table view (or if this is a UITableViewController, then they’re the same thing).
In viewDidLoad:
Then, in the handleSwipe method: