37
votes

I am creating one table view based application. I have created a custom table cell for table, that contains 2 labels, 1 image and 1 button. The table view Data source method is working properly. I am using xib for both custom cell and view controller class and i connect delegate and data source to the file's owner. But the problem is when i select the table row, didSelectRowAtIndexPath is not getting fire. As mentioned the only way to fire it is to hold down on the cell for about 3-4 seconds. Does anyone have any idea why this is happening?

Thanks for any pointers...

Here is my table view methods..

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [finalAddonsArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    NewCustomCell *cell = (NewCustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        NSArray *nib=[[NSBundle mainBundle]loadNibNamed:@"NewCustomCell" owner:self options:nil];
        cell=[nib objectAtIndex:0];
    }

    Addons *addons1=[[Addons alloc]init];
    addons1= [finalAddonsArray objectAtIndex:indexPath.row];

    if (addons1.data == nil) {
        cell.ivCategory.image = [UIImage imageNamed:@"blogo.jpg"];
    }
    else
    {
        cell.ivCategory.image=[UIImage imageWithData:addons1.data];
    }

    cell.lblTitle.text = addons1.name;
    if (addons1.price == nil) {
        cell.lblPrice.text = nil;
    }
    else{
        cell.lblPrice.text = [NSString stringWithFormat:@"%@ rs",addons1.price];
    }
    [cell.button addTarget:self
                    action:@selector(editButtonPressed:)
          forControlEvents:UIControlEventTouchUpInside];

    cell.button.tag=indexPath.row;
    index = indexPath;
    cell.selectionStyle = UITableViewCellSelectionStyleGray;

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"sjcjksbcjksbcfkebscf1234567890");
}

One more thing i am getting that if i am using default UITableViewCell instead of custom cell then also my problem is same, delegate method is not getting fire.

Custom cell properties:

enter image description hereenter image description here

7
Where is the didSelectRowAtIndexPath method?geekchic
Why do you determine it gets fired late? Are you absolutely sure it takes 3-4 seconds or does the action you expect only occur then? Add an NSLog or breakpoint to the first line of didSelectRowAtIndexPath. Also - what is the size of the button in the cell?Stavash
@nikhitaI am updating my question with didSelectRowAtIndexPath method.Anand Gautam
if you are pushing a view Controller from didSelectRowAtIndexPath i think nextViewcontroller load some data from web-service. thays why that pushing a viewcontroller take 3_4 second and you thought didSelectRowAtIndexPath selecting cell take some time.Nitin Gohel
How about cell highlighting? Does it occur immediately or only after a delay as well? Any active UIGestureRecognizer around?Stavash

7 Answers

99
votes

same problem happened with me because I have added a tap gesture recogniser over it. If you have used any gesture recognizer try removing it and check if it causing the problem.

EDIT: Solution as commented by the Ali: If you have used tap gesture you can use [tap setCancelsTouchesInView:NO];

2
votes

I was faced with a similar issue:

For me, the problem was because my UITableView was added to an UIScrollView and more specifically to its contentView. It appears that inside the contentView, I had to stay press 2-3 sec to fire the didSelectRowAtIndexPath method.

I moved my TableView to self.view instead of contentView and it solved the problem!

2
votes

Maybe you will call the method

[tableView deselectRowAtIndexPath:indexPath animated:NO];

before Push ViewController or Other Operation. Like

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // 1. manual call this method to deSelect Other Cell
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    // 2. than do other operation
    PushViewController Or Some Animation ....
}

that`s solve my problem .

2
votes

As others suggested, [tap setCancelsTouchesInView:NO]; does the trick. However, I want to make one thing clear:

If you think that you did not implement tapgesture and are curious about why you had to add your view into the protected views, check out your class because most probably you have inherited some class and that class includes tap gesture recognizer in it.

In my case, I did the following:

- (NSMutableArray *)tapProtectedViews
{
    NSMutableArray *views = [super tapProtectedViews];
    [views addObject:self.mTableView];
    return views;
}

Edit for Swift 4+

Assuming you have a UITapGestureRecognizer instance named tapGesture:

func disableTapGesture(){
    tapGesture.cancelsTouchesInView = false
}

Or you can:

if self.view.gestureRecognizers?.isEmpty == false{
    for recognizer in self.view.gestureRecognizers!{
        self.view.removeGestureRecognizer(recognizer)
    }
 }
0
votes

Dear i faced the same problem. When i tapped the cell but didselectrowatindexpath was not called than it was suddenly called when i released the button after pressing it for few seconds.

If you are facing the same issue there must be a 1. UITapGestureRecognizer that is creating problem for you or 2. a scroll view in which you placed you table view.

Thus you should remove the gesture or the super scroll view in which your table view is placed

0
votes

If you have custom gesture object on your view, check override func gestureRecognizerShouldBegin(_ gesture: UIGestureRecognizer) -> Bool delegate. Compare custom gesture with sender gesture, If its not custom gesture object, pass it to the the super. So system gestures/taps won't get blocked.

-2
votes

I'm not sure about this, but Delays Content Touches might have something to do with it.