Search code examples
ioscocoa-touchuitableviewuigesturerecognizer

UIGestureRecognizer in table view cell get indexPath always return the indexPath of the last cell


I have a UIImageView inside UITaleViewCell, I added a tap recognizer to the UIImageView.

- (IBAction)ui_tapped:(UITapGestureRecognizer *)sender {
    NSIndexPath *indexPath = [CocoaHelper indexPathWithTableView:self.tableView sender:sender.view];

    RichMediaViewController *viewController = (RichMediaViewController *)[CocoaHelper viewControllerWithIdentifier:VC_RICH_MEDIA];
    Message *message = self.messages[indexPath.row];
    [viewController setupWithEntity:message];
    [self presentViewController:viewController animated:YES completion:nil];


}

+ (NSIndexPath *)indexPathWithTableView:(UITableView *)tableView sender:(id)sender {

    CGPoint hitPoint = [sender convertPoint:CGPointZero toView:tableView];
    NSIndexPath *hitIndex = [tableView indexPathForRowAtPoint:hitPoint];
    return hitIndex;

}

I used + (NSIndexPath *)indexPathWithTableView:(UITableView *)tableView sender:(id)sender for buttons inside cells and it is correct, but for gesture, it always returns the cell of the last index path.

enter image description here

enter image description here

EDIT

Hard-coding the tap recognizer works

if ([message.type isEqualToString:@"image"]) {
    UIImageView *view = ((ImageMessageCell *)cell).imageView;
    UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(ui_tapped:)];
    [view setGestureRecognizers:[NSArray arrayWithObject:tapRec]];
}

This is very tedious coding (since I need to check for each types of cells including image, video and other rich media), please post your answer if you know how to add it from the storyboard


Solution

  • It turns out that it's not able to add gesture recognizer to each instantiated prototype cell separately, i.e. only one gesture recognizer for all the cells instantiated from the same prototype cell.

    Solved this problem by using UIButton with background image view instead of using image view.

    [self.imageButton setBackgroundImage:[UIImage imageNamed:LOADING_IMAGE_FILE] forState:UIControlStateNormal];
    NSData *blob = post.thumbnailBlob;
    if (blob) {
        [self.imageButton setBackgroundImage:[UIImage imageWithData:blob] forState:UIControlStateNormal];
    }