How get UITableView IndexPath from UITableView iphone?

In my iPhone app I have one messaging screen. I have added UITapGestureRecognizer on the UIViewController and also I have a UITableview on the screen. I want to select the UITableViewCell but I can’t select the UITableView because of UITapGestureRecognizer. When I touch the screen, only the tap gesture action is called but UITableView delegate didSelectRowAtIndexPath: is not called. Could anyone please help me to work on both tap gesture and UITableView:didSelectRowAtIndexPath:. Thanks in advance.

  • Are Xamarin iOS apps bloated unreasonably?
  • Working with NSDate components in Swift
  • pageshow event on iphone fires only once
  • Reverse Geocode Location in Swift
  • Deallocate SKScene after transition to another SKScene in SpriteKit
  • Why UICollectionView's UICollectionViewCell is not highlighting on user touch?
  • 4 Solutions Collect From Internet About “How get UITableView IndexPath from UITableView iphone?”

    While I prefer Matt Meyer’s suggestion or my other suggestion of using a custom gesture recognizer, another solution, not involving custom gesture recognizers, would be to have your tap gesture recognizer identify whether you tapped on a cell in your tableview, and if so, manually invoke didSelectRowAtIndexPath, e.g.:

    - (void)handleTap:(UITapGestureRecognizer *)sender
    {
        CGPoint location = [sender locationInView:self.view];
    
        if (CGRectContainsPoint([self.view convertRect:self.tableView.frame fromView:self.tableView.superview], location))
        {
            CGPoint locationInTableview = [self.tableView convertPoint:location fromView:self.view];
            NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:locationInTableview];
            if (indexPath)
                [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
    
            return;
        }
    
        // otherwise proceed with the rest of your tap handling logic
    }
    

    This is suboptimal because if you’re doing anything sophisticated with your tableview (e.g. in cell editing, custom controls, etc.), you lose that behavior, but if you’re just looking to receive the didSelectRowAtIndexPath, then this might do the job. The other two approaches (separate views or the custom gesture recognizer) let you retain the full tableview functionality, but this could work if you just need something simple and you don’t need the rest of the tableview’s built-in capabilities.

    You can use the TagGesture delegate:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        if ([touch.view isDescendantOfView:yourTableView]) {
            return NO;
        }
    
        return YES;
    }
    

    Hope this helps.

    An easier way to do this is to have two views: one containing the view that you want the tap gesture to be on, and one containing the tableview. You can attach the UITapGestureRecognizer to the view you want it to work on, and then it won’t block your UITableView.

    Assuming you want the tap gesture to work everywhere except over the tableview, you could subclass the tap gesture recognizer, creating a recognizer that will ignore any subviews included in an array of excludedViews, preventing them from generating a successful gesture (thus passing it on to didSelectRowAtIndexPath or whatever):

    #import <UIKit/UIGestureRecognizerSubclass.h>
    
    @interface MyTapGestureRecognizer : UITapGestureRecognizer
    @property (nonatomic, strong) NSMutableArray *excludedViews;
    @end
    
    @implementation MyTapGestureRecognizer
    
    @synthesize excludedViews = _excludedViews;
    
    - (id)initWithTarget:(id)target action:(SEL)action
    {
        self = [super initWithTarget:target action:action];
        if (self)
        {
            _excludedViews = [[NSMutableArray alloc] init];
        }
    
        return self;
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [super touchesBegan:touches withEvent:event];
    
        CGPoint location = [[touches anyObject] locationInView:self.view];
    
        for (UIView *excludedView in self.excludedViews)
        {
            CGRect frame = [self.view convertRect:excludedView.frame fromView:excludedView.superview];
    
            if (CGRectContainsPoint(frame, location))
                self.state = UIGestureRecognizerStateFailed;
        }
    }
    
    @end
    

    And then, when you want to use it, just specify what controls you want to exclude:

    MyTapGestureRecognizer *tap = [[MyTapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [tap.excludedViews addObject:self.tableView];
    [self.view addGestureRecognizer:tap];