0

I have the following error. 'indexPath' undeclared (first use in this function).

Code. didSelectRowAtIndexPath

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

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
cell.accessoryView = spinner;
[spinner startAnimating];
[spinner release];

[self performSelector:@selector(pushDetailView:) withObject:tableView afterDelay:0.1];
}

pushDetailView

- (void)pushDetailView:(UITableView *)tableView {

// Push the detail view here
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//load the clicked cell.
DetailsImageCell *cell = (DetailsImageCell *)[tableView cellForRowAtIndexPath:indexPath];

//init the controller.
AlertsDetailsView *controller = nil;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
controller = [[AlertsDetailsView alloc] initWithNibName:@"DetailsView_iPad" bundle:nil];
} else {
controller = [[AlertsDetailsView alloc] initWithNibName:@"DetailsView" bundle:nil];
}

//set the ID and call JSON in the controller.
[controller setID:[cell getID]];

//show the view.
[self.navigationController pushViewController:controller animated:YES];
}

I think it's because I'm not parsing the indexPath value from didSelectRowAtIndexPath to pushDetailView but I don't know how to approach this.

Could someone please advise?

Thanks.

K.Honda
  • 3,106
  • 5
  • 26
  • 37

2 Answers2

3

The problem is that you pushDetailView: method has no indexPath variable on it's scope.

Instead of

- (void)pushDetailView:(UITableView *)tableView {

You should make your method like this:

- (void)pushDetailView:(UITableView *)tableView andIndexPath: (NSIndexPath*) indexPath {

and then indexPath would be declared on the method scope.

Then, inside your didSelectRowAtIndexPath method, replace

[self performSelector:@selector(pushDetailView:) withObject:tableView afterDelay:0.1];

for the code bellow:

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self pushDetailView: tableView andIndexPath: indexPath];
});

This uses GCD to execute the code after a delay, instead of the performSelector: withObject :afterDelay: and here is a nice post explaining why sometimes is better to opt for this aproach

Community
  • 1
  • 1
Felipe Sabino
  • 17,825
  • 6
  • 78
  • 112
  • Cool... So I can use `- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath` and `- (void)pushDetailView:(UITableView *)tableView andIndexPath: (NSIndexPath*) indexPath` at the same time? – K.Honda Jun 15 '11 at 13:44
  • What do you mean by 'at the same time'? – Felipe Sabino Jun 15 '11 at 13:57
  • Well... I edited the code explaining exactly what you should do... Let me know if you have any doubts :) – Felipe Sabino Jun 15 '11 at 14:00
  • @Felipe: It's successfully pushing to the new view. Thanks. One problem though; when I go to the next view and go back again, the arrow on the cell I clicked disappears. Why? Also, there are 2 warnings though. First one is on:`[self pushDetailView: tableView andIndexPath: indexPath];`. -> **Method '-pushDetailView:andIndexPath.' not found (return type defaults to 'id')**. Second is: `- (void)pushDetailView:(UITableView *)tableView andIndexPath: (NSIndexPath*) indexPath`. -> **'Alerts' may not respond to '-pushDetailView:andIndexPath'**. Do you know why? Thanks a lot. – K.Honda Jun 16 '11 at 13:21
  • I guess the arrow disappears because you replace it (in you accessoryView) by the `spinner` object. and the warning is probably because you haven't updated the method new signature into your .h file and then the compiler thinks this method may not exist – Felipe Sabino Jun 16 '11 at 13:33
  • @Felipe: All's working now! I referenced the method in the .h file and fixed the arrow issue with `UIView *activityView = cell.accessoryView;`. Thanks. – K.Honda Jun 16 '11 at 13:41
0

Since you need to provide two arguments and perform after a delay package both arguments in an NSDictionary and pass it:

    NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
    tableView, @"tableView", indexPath, @"indexPath", nil];
    [self performSelector:@selector(pushDetailView:) withObject:arguments afterDelay:0.1];
    ...

- (void)pushDetailView:(NSDictionary *)arguments {
    UITableView *tableView = [arguments objectForKey:@"tableView"];
    NSIndexPath *indexPath = [arguments objectForKey:@"indexPath"];
    ...

Or as @Felipe suggests, use GCD.

zaph
  • 111,848
  • 21
  • 189
  • 228