[ios] -didSelectRowAtIndexPath: not being called

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?

This question is related to ios uitableview cocoa-touch didselectrowatindexpath

The answer is


This was probably only in my case, but I had reloaded some files from a backup and things were not working, including this. After doing a full clean (Product > Clean or Shift + Command + K) it worked. Probably something got messed up in a precompiled header. Chances are that's not the problem for you, but it's worth a shot.


you must check this selection must be single selection and editing must be no seleciton during edition and you change setting in uttableviewcell properties also you edit in table view cell style must be custom and identifier must be Rid and section is none


In my case the problem was I had a UITableViewCell subclass and I'd implemented these two methods: touchesBegan:withEvent: & touchesEnded:withEvent to handle a fancy animation on touch. But I'd forgotten to add the [super touchesBegan:touches withEvent:event]; method ad [super touchesEnded:touches withEvent:event]; to also inform the parent of cell of the touch.

So changing the code to following solved my problem:

-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    [super touchesBegan:touches withEvent:event];
    //blah blah blah
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    //rest of the code
}

Another possible cause seems to be that the UITableView is embed in a UIScrollView. I had this problem today because I inadvertently had a scroll view instead of a normal view as the root view of my controller.


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.


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.


I just found another way to not get your didSelect method called. At some point, prolly during some error in func declaration itself, XCode suggested I add @nonobjc to my method :

@nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

This will continue to compile without complaint but you will never get called by the ui actions.

"That's my two cents and I'll be wanting my change back"


If the cell you are clicking is being highlighted but the function is still not being called, double check your function's signature. It should look like this:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

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.


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

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];

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...


you must check this selection must be single selection and editing must be no seleciton during edition and you change setting in uttableviewcell properties also you edit in table view cell style must be custom and identifier must be Rid and section is none


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

UITableView selection kind

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

To do this programmatically, do:

tableView.allowsSelection = YES

In my case, just one cell was having this problem. The cell included UITextView outlet in readonly mode. Though it was readonly before tap. Upon tapping, keyboard rose. It turned out that it still needed to disable the interaction.

cell.content.scrollEnabled = NO;
cell.content.editable = NO;
cell.content.userInteractionEnabled = NO;
cell.content.delegate = nil;

[cell.content resignFirstResponder];


I can't comment, write here. In my case didSelectRow worked, but not didDeselectRow. I set delegate and dataSource for tableView and this solved my case.


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.


I had this issue, when the class name of my TableViewController had been set incorrectly in the Interface Builder.


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.


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;
}

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

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];

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.


Another possible cause seems to be that the UITableView is embed in a UIScrollView. I had this problem today because I inadvertently had a scroll view instead of a normal view as the root view of my controller.


In my case the problem was I had a UITableViewCell subclass and I'd implemented these two methods: touchesBegan:withEvent: & touchesEnded:withEvent to handle a fancy animation on touch. But I'd forgotten to add the [super touchesBegan:touches withEvent:event]; method ad [super touchesEnded:touches withEvent:event]; to also inform the parent of cell of the touch.

So changing the code to following solved my problem:

-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    [super touchesBegan:touches withEvent:event];
    //blah blah blah
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    //rest of the code
}

In my case, the problem was declaring the method as a private.

This didn't work:

private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

This worked:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

I'm not sure if anybody scrolls far enough to see this answer but since this is the most popular question about this subject and the answer wasn't there I'll add it:

As of Xcode 9 / Swift 4 all Objective-C methods should be marked @objc. The compiler does a reasonable job of recognizing where it should be applied however it doesn't figure out inheritance. For example:

class Delegate: NSObject, UITableViewDelegate {
}

class SuperDelegate: Delegate {
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}

This will not generate any warning, crashing or build error. However your line will not be called until you add @objc:

@objc class SuperDelegate: Delegate {
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}

Check if -heightForRowAtIndexPath doesnt return 0.


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.


I was having problem that control was not going in to didselect row after applying break point. problem was in view. I removed tab gesture from view. then its worked fine


Another crazy possibility: I was running my app on an iPhone 5S, and I used:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

as I always did in the past.

However, I didn't look closely enough at my compiler warnings... it said I should change that above line to:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

64-bit compatibility! shakes fist

Be on the lookout in case you start pulling your hair out.


Check if your viewController has following method:

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

if you return "NO" didSelectRow won't be called


If You have a custom cell, remember to set UserInteractionEnabled in the Xib (or via code) for the cell.


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.


I can't comment, write here. In my case didSelectRow worked, but not didDeselectRow. I set delegate and dataSource for tableView and this solved my case.


I just found another way to not get your didSelect method called. At some point, prolly during some error in func declaration itself, XCode suggested I add @nonobjc to my method :

@nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

This will continue to compile without complaint but you will never get called by the ui actions.

"That's my two cents and I'll be wanting my change back"


Take care about the UITableView properties in the storyboard, what happened in my case was that I had the combox in the storyboard selected as "Selection: Single Selection", that does not allow the method didSelectRowAtIndexPath run.


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 :)


I've just had this issue, however it didn't occur straight away; after selecting a few cells they would stop calling didSelectItemAtIndexPath. I realised that the problem was the collection view had allowsMultipleSelection set to TRUE. Because cells were never getting deselected this stopped future calls from calling didSelectItemAtIndexPath.


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 ??


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:.


I iterated all previous answers but none of them helped me. After some trial and error I found a different solution. I had a UIImageView covering the whole cell (as a background). By default a UIImageView has user interaction disabled. By enabling the imageviews user interaction delegate method -didSelectRowAtIndexPath: was called again. eg.

cell.imgView.userInteractionEnabled = YES;

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.


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:.


tableView?.allowsSelection = true

It's False by default in Xcode 11.7


I was having this problem intermittently. Sometimes touching a cell would cause it to be selected. Sometimes it would not receive the touch event.

I am using a features introduced in ios8 called self-sizing cells. I came across this blog post that points out that:

When the table view is first displayed, you may find some of the cells are not sized properly. But when you scroll the table view, the new cells are displayed with correct row height. To workaround this issue, you can force a reload after the view appears:

override func viewDidAppear(animated: Bool) {
    tableView.reloadData()
}

This fixed the issue for me. Even though the table view was rendering correctly, touch handling (specifically hitTest of UITableView) seemed to be subject to the above-mentioned bug.


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

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


Make sure you call reloadData on the main thread. If you are calling that method from some kind of asynchronous method (eg: a network request of some sort), the table view may or may not respond properly (in some cases the app can even crash).

Use a main thread code block to perform the reloadData call, if the call is being made in some other method block (which you are unsure of):

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [tableView reloadData];
}];

I have read all the answers and strongly agree with them. But it is entirely different in my case. I had new segue for my detailViewController linked directly to my tableCell in StoryBoard which caused this. So I had to remove that segue from my cell and linked it with the UITableViewController itself. Now by writing the following code it works,

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        // Do any operation
        performSegue(withIdentifier: "DetailSegue", sender: self)
    }

Hope this solution will help someone out there!


If the problem arise with UITapGestureRecognizer you can fix this:

  • in Storyboard:

enter image description here

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

If the cell you are clicking is being highlighted but the function is still not being called, double check your function's signature. It should look like this:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

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.


In my case, the problem was declaring the method as a private.

This didn't work:

private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

This worked:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

I had a call to cell.userInteractionEnabled buried in some customized table code.

Stupid, yet aren't most bugs?


I had this problem myself. I had built the bones of the view in IB (just a View and a TableView) and the delegate wasn't set. I wired it up to File's Owner and it worked like a charm. ::save::


I have read all the answers and strongly agree with them. But it is entirely different in my case. I had new segue for my detailViewController linked directly to my tableCell in StoryBoard which caused this. So I had to remove that segue from my cell and linked it with the UITableViewController itself. Now by writing the following code it works,

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        // Do any operation
        performSegue(withIdentifier: "DetailSegue", sender: self)
    }

Hope this solution will help someone out there!


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.


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


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


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...


I've just had this issue, however it didn't occur straight away; after selecting a few cells they would stop calling didSelectItemAtIndexPath. I realised that the problem was the collection view had allowsMultipleSelection set to TRUE. Because cells were never getting deselected this stopped future calls from calling didSelectItemAtIndexPath.


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".


YOU MUST select these options

enter image description here

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 image description here


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.


Another crazy possibility: I was running my app on an iPhone 5S, and I used:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

as I always did in the past.

However, I didn't look closely enough at my compiler warnings... it said I should change that above line to:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

64-bit compatibility! shakes fist

Be on the lookout in case you start pulling your hair out.


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 ...


This was probably only in my case, but I had reloaded some files from a backup and things were not working, including this. After doing a full clean (Product > Clean or Shift + Command + K) it worked. Probably something got messed up in a precompiled header. Chances are that's not the problem for you, but it's worth a shot.


I had this issue, when the class name of my TableViewController had been set incorrectly in the Interface Builder.


  1. Add @interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>

  2. Make delegation in the storyboard

enter image description here

  1. Add code

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
       NSString *cellText = cell.textLabel.text;
    }
    

tableView?.allowsSelection = true

It's False by default in Xcode 11.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.


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 image description here


Make sure you call reloadData on the main thread. If you are calling that method from some kind of asynchronous method (eg: a network request of some sort), the table view may or may not respond properly (in some cases the app can even crash).

Use a main thread code block to perform the reloadData call, if the call is being made in some other method block (which you are unsure of):

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [tableView reloadData];
}];

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.


YOU MUST select these options

enter image description here

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 image description here


I had this problem myself. I had built the bones of the view in IB (just a View and a TableView) and the delegate wasn't set. I wired it up to File's Owner and it worked like a charm. ::save::


I had a call to cell.userInteractionEnabled buried in some customized table code.

Stupid, yet aren't most bugs?


I'm not sure if anybody scrolls far enough to see this answer but since this is the most popular question about this subject and the answer wasn't there I'll add it:

As of Xcode 9 / Swift 4 all Objective-C methods should be marked @objc. The compiler does a reasonable job of recognizing where it should be applied however it doesn't figure out inheritance. For example:

class Delegate: NSObject, UITableViewDelegate {
}

class SuperDelegate: Delegate {
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}

This will not generate any warning, crashing or build error. However your line will not be called until you add @objc:

@objc class SuperDelegate: Delegate {
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}

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.


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.


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


Check if your viewController has following method:

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

if you return "NO" didSelectRow won't be called


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.


I was having problem that control was not going in to didselect row after applying break point. problem was in view. I removed tab gesture from view. then its worked fine


In my case, just one cell was having this problem. The cell included UITextView outlet in readonly mode. Though it was readonly before tap. Upon tapping, keyboard rose. It turned out that it still needed to disable the interaction.

cell.content.scrollEnabled = NO;
cell.content.editable = NO;
cell.content.userInteractionEnabled = NO;
cell.content.delegate = nil;

[cell.content resignFirstResponder];


Check if -heightForRowAtIndexPath doesnt return 0.


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.


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 ...


I was having this problem intermittently. Sometimes touching a cell would cause it to be selected. Sometimes it would not receive the touch event.

I am using a features introduced in ios8 called self-sizing cells. I came across this blog post that points out that:

When the table view is first displayed, you may find some of the cells are not sized properly. But when you scroll the table view, the new cells are displayed with correct row height. To workaround this issue, you can force a reload after the view appears:

override func viewDidAppear(animated: Bool) {
    tableView.reloadData()
}

This fixed the issue for me. Even though the table view was rendering correctly, touch handling (specifically hitTest of UITableView) seemed to be subject to the above-mentioned bug.


If You have a custom cell, remember to set UserInteractionEnabled in the Xib (or via code) for the cell.


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;
}

Take care about the UITableView properties in the storyboard, what happened in my case was that I had the combox in the storyboard selected as "Selection: Single Selection", that does not allow the method didSelectRowAtIndexPath run.


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.


Please check for UITapGestureRecognizer. In my case tapgesture was added for the view where tableview got placed, which is eating the user interaction of UITableview like didselect. After disabling tapgesture for the view, didselect delegate was triggered.


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


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;
}

  1. Add @interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>

  2. Make delegation in the storyboard

enter image description here

  1. Add code

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
       NSString *cellText = cell.textLabel.text;
    }
    

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 image description here


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

UITableView selection kind

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

To do this programmatically, do:

tableView.allowsSelection = YES

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 image description here


in mine case i did a small mistake is I assigned:

tableView.isUserInteractionEnabled = false

it should be:

tableView.isUserInteractionEnabled = true

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.


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

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


If the problem arise with UITapGestureRecognizer you can fix this:

  • in Storyboard:

enter image description here

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

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.


I iterated all previous answers but none of them helped me. After some trial and error I found a different solution. I had a UIImageView covering the whole cell (as a background). By default a UIImageView has user interaction disabled. By enabling the imageviews user interaction delegate method -didSelectRowAtIndexPath: was called again. eg.

cell.imgView.userInteractionEnabled = YES;

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.


There are some amazing clues and answers in this post (maybe one of the best discussions I've seen!) The clues in here helped me figure out what my issue was, but I still spent many hours drooling on my keyboard trying to discover the issue, which was similar to other posts. However, how I finally discovered it was a bit different, so I wanted to share in case others come across it too.

Turns out my issue was that, in code, a superclass was adding a full-screen "error view" that was not hidden, but transparent. However, because it was over the tableview and "user action" was set to YES, it was intercepting my touches on the tableview.

I diagnosed this using Xcode's cool "Debug View Hierarchy" button. Here is a screen shot with annotations that hopefully explain what I did and how I ultimately diagnosed the issue.

In code, I simply had to do:

errorMessageView.setUserInteractionEnabled = NO;
// or
errorMessageView.hidden = YES;

Debug View Hierarchy


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


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


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;
}

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 ??


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 :)


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 image description here


in mine case i did a small mistake is I assigned:

tableView.isUserInteractionEnabled = false

it should be:

tableView.isUserInteractionEnabled = true

Please check for UITapGestureRecognizer. In my case tapgesture was added for the view where tableview got placed, which is eating the user interaction of UITableview like didselect. After disabling tapgesture for the view, didselect delegate was triggered.


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.


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.


There are some amazing clues and answers in this post (maybe one of the best discussions I've seen!) The clues in here helped me figure out what my issue was, but I still spent many hours drooling on my keyboard trying to discover the issue, which was similar to other posts. However, how I finally discovered it was a bit different, so I wanted to share in case others come across it too.

Turns out my issue was that, in code, a superclass was adding a full-screen "error view" that was not hidden, but transparent. However, because it was over the tableview and "user action" was set to YES, it was intercepting my touches on the tableview.

I diagnosed this using Xcode's cool "Debug View Hierarchy" button. Here is a screen shot with annotations that hopefully explain what I did and how I ultimately diagnosed the issue.

In code, I simply had to do:

errorMessageView.setUserInteractionEnabled = NO;
// or
errorMessageView.hidden = YES;

Debug View Hierarchy


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".


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to uitableview

Adding a UISegmentedControl to UITableView make UITableViewCell selectable only while editing How to fix Error: this class is not key value coding-compliant for the key tableView.' UITableView example for Swift Swift - how to make custom header for UITableView? How to insert new cell into UITableView in Swift How to detect tableView cell touched or clicked in swift Dynamic Height Issue for UITableView Cells (Swift) UIButton action in table view cell How to get the indexpath.row when an element is activated?

Examples related to cocoa-touch

Include of non-modular header inside framework module Move textfield when keyboard appears swift Create space at the beginning of a UITextField Navigation bar with UIImage for title Generate a UUID on iOS from Swift How do I write a custom init for a UIView subclass in Swift? creating custom tableview cells in swift How would I create a UIAlertView in Swift? Get current NSDate in timestamp format How do you add an in-app purchase to an iOS application?

Examples related to didselectrowatindexpath

-didSelectRowAtIndexPath: not being called