Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone: didSelectRowAtIndexPath not invoked

I know this issue being mentioned before, but resolutions there didn't apply. I'm having a UINavigationController with an embedded UITableViewController set up using IB. In IB the UITableView's delegate and dataSource are both set to my derivation of UITableViewController. This class has been added using XCode's templates for UITableViewController classes. There is no custom UITableViewCell and the table view is using default plain style with single title, only.

Well, in simulator the list is rendered properly, with two elements provided by dataSource, so dataSource is linked properly. If I remove the outlet link for dataSource in IB, an empty table is rendered instead.

As soon as I tap on one of these two items, it is flashing blue and the GDB encounters interruption in __forwarding__ in scope of a UITableView::_selectRowAtIndexPath. It's not reaching breakpoint set in my non-empty method didSelectRowIndexPath. I checked the arguments and method's name to exclude typos resulting in different selector.

I recently didn't succeed in whether delegate is set properly, but as it is set equivalently to dataSource which is getting two elements from the same class, I expect it to be set properly. So, what's wrong?

I'm running iPhone/iPad SDK 3.1.2 ... but tried with iPhone SDK 3.1 in simulator as well.

EDIT: This is the code of my UITableViewController derivation:

#import "LocalBrowserListController.h"
#import "InstrumentDescriptor.h"

@implementation LocalBrowserListController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self listLocalInstruments];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
    [super viewDidUnload];
}

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

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

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    if ( ( [entries count] > 0 ) && ( [indexPath length] > 0 ) )
        cell.textLabel.text = [[[entries objectAtIndex:[indexPath indexAtPosition:[indexPath length] - 1]] label] retain];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if ( ( [entries count] > 0 ) && ( [indexPath length] > 0 ) )
    {
        ...
    }
}

- (void)dealloc {
    [super dealloc];
}

- (void) listLocalInstruments {
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:10];

    [result addObject:[InstrumentDescriptor descriptorOn:[[NSBundle mainBundle] pathForResource:@"example" ofType:@"idl"] withLabel:@"Default 1"]];
    [result addObject:[InstrumentDescriptor descriptorOn:[[NSBundle mainBundle] pathForResource:@"example" ofType:@"xml"] withLabel:@"Default 2"]];

    [entries release];
    entries = [[NSArray alloc] initWithArray:result];
}

@end
like image 352
soletan Avatar asked Feb 21 '10 12:02

soletan


3 Answers

Apple's documentation says that didSelectRowAtIndexPath:index will not be invoked when selectRowAtIndexPath:indexPath is called. To call didSelectRowAtIndexPath use the following:

[[tableView delegate] tableView:tableView didSelectRowAtIndexPath:index];

This basically invokes the delegate.

like image 118
RPM Avatar answered Oct 31 '22 18:10

RPM


Try didSelectRowAtIndexPath. The selector as you typed it was missing the word "At" in the selector name.

Are you calling


- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition

If you are, then that will not call the delegate methods tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath: You will have to call them yourself.

See the UITableView Reference.

For what it's worth I have not seen any difference in the table view behavior in the 3.0.x or 3.1.x releases.

like image 3
Mark Avatar answered Oct 31 '22 18:10

Mark


Well, after trying to retain the delegate of UITableView instance just to check for leaking memory with success, I investigated on that issue and stumbled over some tutorials on how to combine views and controllers using detached NIBs as I do here. This tutorial finally made me do the trick:

Combining View Controllers

Focusing on error in detail there were two UITableViewControllers ... one in main NIB set as root controller for a tabbed Navigation controller and a second time in referenced NIB used to provide a raw UITableView instance instead.

like image 2
soletan Avatar answered Oct 31 '22 20:10

soletan