Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting touch inside UITableViewCell subview

I am unclear where I should add the UIGestureRecognizer code to corresponding subviews of a UITableViewCell. I have read all the related questions I could find. Right now my cells and cell's subviewsare generated inside of cellForRowAtIndexPath. I have tried to add the Gesture inside of cellForRowAtIndexPath with this:

UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[mySubview addGestureRecognizer:tapGesture];
tapGesture.cancelsTouchesInView = YES;
tapGesture.delegate = self;

However, this detects nothing. To verify my UIGesture recognizer is working I have used the above code on the tableView itself, and it does register touches as expected. Furthermore, when the tableView has the above gesture attached the below code is also being called as expected:

-(BOOL) gestureRecognizer:(UITapGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    NSLog(@"shouldRevceiveTouch");
    return YES;
}

- (BOOL)gestureRecognizer:(UITapGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UITapGestureRecognizer *)otherGestureRecognizer 
{
    NSLog(@"simultaneously");
    return YES;
}

I have tried to remove the GestureRecognizer from the tableView and inside of cellForRowAtIndexPath I have tried to attach the GestureRecognizer to the cell itself, any of its subviews, nothing else gets a touch detected. (None of the above code is triggered)

Clearly I am adding the GestureRecognizer incorrectly. Where/When would be an appropriate location/time to add the GestureRecognizer?

Thank you.

like image 739
tpdietz Avatar asked Jul 23 '14 15:07

tpdietz


2 Answers

I've done similar thing, but it was UILongPressGestureRecognizer. I think there is no big difference (because all touches are received by UITableView). I've added gesture recognizer in controllers viewDidLoad method (NOT IN cell).

- (void) tableViewLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
    CGPoint p = [gestureRecognizer locationInView:self.messageTableView];

    NSIndexPath *indexPath = [self.messageTableView indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row");
    else {
        UITableViewCell *cell = [self.messageTableView cellForRowAtIndexPath:indexPath];
        CGPoint pointInCell = [cell convertPoint:p fromView:self.messageTableView];
    }
}

You can change Long press to regular one and try it yourself

like image 151
Nikita Took Avatar answered Oct 14 '22 16:10

Nikita Took


I needed to detect touches on different subviews inside my cell. also handling iOS 9's UITableViewCellContentView.

First I overrided touchesBegan inside the my custom UITableViewCell

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:touch.view];

    // Imagine I have 2 labels inside my cell
    CGPoint convertedPoint = [self.firstLabel convertPoint:point fromView:touch.view];
    if ([self.firstLabel pointInside:convertedPoint withEvent:nil]) {
        // Touched first label
        return;
    } 

    convertedPoint = [self.secondLabel convertPoint:point fromView:touch.view];
    if ([self.secondLabel pointInside:convertedPoint withEvent:nil]) {
        // Touched second label
        return;
    } 

    // no labels touched, call super which will call didSelectRowAtIndexPath
    [super touchesBegan:touches withEvent:event];
}

And to fix support in iOS 9 we should override awakeFromNib or just disable the cell user intercations somehwere else if cell is not in Storyboard / xib:

- (void)awakeFromNib {
    // Initialization code
    self.contentView.userInteractionEnabled = NO;
} 

of course we shouldn't forget to set our label user interactions enabled.

like image 29
Danpe Avatar answered Oct 14 '22 14:10

Danpe