简体   繁体   中英

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.

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

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.

Not sure exactly what you are trying to do. If you just want to detect if the user taps on a cell within the table then you don't need to implement a gesture recognizer. Just implement the delegate method below to detect when a row from the table has been selected then process the elements of the row such as getting the subview, etc.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   // Do all my cool tap related stuff here for example, get the row that was tapped:
   UITableViewCell *cell= [tableView cellForRowAtIndexPath:indexPath];
   // get your subview (assume its a UIImageView) from cell - one way to do it below
   UIImageView photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
}

If you describe your problem a little further then perhaps I can offer additional suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM