-didSelectRowAtIndexPath: not being called

2019-01-01 12:58发布

问题:

I\'m writing an iOS app with a table view inside a tab view. In my UITableViewController, I implemented -tableView:didSelectRowAtIndexPath:, but when I select a row at runtime, the method isn\'t being called. The table view is being populated though, so I know that other tableView methods in my controller are being called.

Does anyone have any ideas what I may have screwed up to make this happen?

回答1:

It sounds like perhaps the class is not the UITableViewDelegate for that table view, though UITableViewController is supposed to set that automatically.

Any chance you reset the delegate to some other class?



回答2:

Just in case someone made the same stupid mistake as I did:

Check out if the method name of what you expect of being didSelect may accidentally be gotten didDeselect in some way. It took about two hours for me to find out ...



回答3:

Another thing that might lead to the issue is not selected selection kind:

\"UITableView

Should be Single Selection for normal selection, should not be No Selection.



回答4:

Another possibility is that a UITapGestureRecognizer could be eating the events, as was the case here: https://stackoverflow.com/a/9248827/214070

I didn\'t suspect this cause, because the table cells would still highlight blue as if the taps were getting through.



回答5:

All good answers, but there\'s one more to look out for...

(Particularly when creating a UITableView programmatically)

Make sure the tableView can respond to selection by setting [tableView setAllowsSelection:YES]; or removing any line that sets it to NO.



回答6:

If the problem arise with UITapGestureRecognizer you can fix this:

  • in Storyboard:

\"enter

in code with Objective-C:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; 
[self.view addGestureRecognizer:tap];

[tap setCancelsTouchesInView:NO];

in code with Swift:

let tap = UITapGestureRecognizer(target: self, action:Selector(\"dismissKeyboard\"))
view.addGestureRecognizer(tap)

tap.cancelsTouchesInView = false


回答7:

I have encountered two things in this situations.

  1. You may have forgot to implement UITableViewDelegate protocol, or there\'s no delegation outlet between your class and your table view.

  2. You might have a UIView inside your row that is a first responder and takes your clicks away. Say a UIButton or something similar.



回答8:

I have had the same problem. And it was hard to find. But somewhere in my code was this:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

It must be return indexPath, else -tableView:didSelectRowAtIndexPath: is not being called.



回答9:

If you added a gestureRecognizer on top of the UITableView, didSelectRowAtIndexPath will not get called.

So you need to use gestureRecognizer delegate method to avoid touch in particular view.

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


回答10:

I\'ve ran into a problem where after months of not looking at my code I forgot that I implemented the following method due to some requirements which were not necessary

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath  *)indexPath{
    return NO;
}

It should be returning YES for a row in order to make it selected.



回答11:

YOU MUST select these options

\"enter

but if you want to make UITableViewnot highlighted on clicking then you should make changes in UITableViewCell properties.

Choose None option for Selection just like below

\"enter



回答12:

In case you have the same problem as me: Apparently, this method won\'t be called if your tableView is in edit mode. You have to set allowsSelectionDuringEditing to true.

Via this question: When editing, `UITableView` does not call didSelectRowAtIndexPath ??



回答13:

I had the same problem,

The reason was using of UITapGestureRecognizer. I wanted the keyboard to dismiss when I tapped anywhere else. I realized that this overrides all tap actions, that is why, didSelectRowAtIndexPath function did not called.

When I comment the rows related with UITapGestureRecognizer, it works. Moreover you can check in the function of UITapGestureRecognizer selector if the tapped is UITableViewCell or not.



回答14:

I had put a UITapGestureRecognizer on my table view to dismiss the keyboard which prevented didSelectRowAtIndexPath: from being called. Hope it helps someone.



回答15:

For Xcode 6.4, Swift 1.2 . The selection \"tag\" had been changed in IB. I don\'t know how and why. Setting it to \"Single Selection\" made my table view cells selectable again. \"enter



回答16:

Even though another answer has been accepted, I\'ll add one more possible problem and solution for people who observe this issue:

If you have automatic reference counting (ARC) turned on, you may find that even after assigning your controller as a delegate of the view, the view\'s messages to the controller are not being received because ARC is deleting the controller. Apparently the UITableView\'s delegate pointer does not count as a reference for the ARC, so if that is the only reference to it, the controller will be dealloc\'d. You can verify whether or not this is happening by implementing the dealloc method on the controller and setting a breakpoint or NSLog call there.

The solution is to keep track of the controller with a strong reference somewhere else, until you are sure you won\'t need it anymore.



回答17:

Remember to set the datasource and delegate in the viewDidLoad method as follows:

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];


回答18:

My problem was none of the above. And so lame. But I thought I would list it here in case it helps someone.

I have a tableViewController that is my \"base\" controller and then I create subclasses of this controller. I was writing all my code in the tableView:didSelectRowAtIndexPath routine in the \"base\" class. Completely forgetting that by default this routine had also been created (albeit with no code that did anything) in all of my subclasses as well. So when I ran my app, it ran the subclass version of the code, did nothing, and made me sad. So of course, once I removed the routine from the subclasses, it used mt \"base\" class routine and I\'m in business.

I know. Don\'t laugh. But maybe this will save someone the hour I lost...



回答19:

Giving my 2 cents on this.

I had a Custom UITableViewCell and there was a button covering the whole cell, so when the touch happened, the button was selected and not the cell.

Either remove the button or in my case, I set User Interation Enable to false on the button, that way the cell was the one selected.



回答20:

If you read this, so still doesn\'t solve the problem.

I have custom cell, where checkbox \"User Interaction Enabled\" was disable. So, I Just switch on it. Good luck.



回答21:

I just had this and as has happened to me in the past it didn\'t work because I didn\'t pay attention to the autocomplete when trying to add the method and I actually end up implementing tableView:didDeselectRowAtIndexPath: instead of tableView:didSelectRowAtIndexPath:.



回答22:

In my case, didSelctRowAtIndexPath not calling is due to that I have selected none in the Selection property of tableView, set to single selection solved my problem

\"enter



回答23:

I know is old and the problem was resolved, but a had similar problem, I thought that the problem was with my custom UITableViewCell, but the solution was completely different - I restart XCode :) and then works ok ! almost like Windows :)



回答24:

If your table view is in editing mode (eg. [tableView setEditing:YES animated:NO];), you need to set tableView.allowsSelectionDuringEditing = YES;



回答25:

Another mistake you could\'ve done (as I did): if you set a segue at the cell, didSelectRowAtIndexPath is not called. You should set your segues at the view controller instead.



回答26:

None of these answers worked for me. After about an hour, I figured out something very insidious:

I have a table view inside a cell of another table view. I decided to make an enclosing view that contains the inner table view, among other things. I called this view contentView and hooked it up in the xib.

Turns out that UITableViewCell already has a contentView and does weird things with it. The issue resolved itself when I renamed the property to mainContentView and reconnected the view to this renamed property.



回答27:

In my case, I dynamically calculate the height of the TableView\'s SuperView at load time. Due to a miscalculation, the TableView was positioned outside of the SuperView. The TableView was drawn fine, however all interaction was disabled (and didSelectRowAtIndexPath was never called). Very hard to detect, since there is no visual indication that the TableView is not \"accessible\".



回答28:

In my case the solution was to change NO to YES in the below function.

iOS 9+

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}


回答29:

Ok, updating here as I just ran into this problem, and my issue was slightly different than found here.

I looked in IB and saw that my delegate WAS set, but it was set incorrectly to VIEW instead of File\'s Owner (right click on table view to see where delegate is pointing to).

Hope that helps someone



回答30:

Make sure you implemented tableView:didSelectRowAtIndexPath and not tableView:didDeSelectRowAtIndexPath

This is gotten me on more than a few occasions !!