swanhella
swanhella

Reputation: 441

How do I make multiple tap handlers per row in an iOS TableView?

I have a list of businesses in a tableview with a few clickable areas. The first is an area to view business details on a separate ViewController, the second is to phone the business, and the third is to locate the business on a map.

I'm new to iOS so I'm not sure of the best way to do this.

In Android, it's fairly easy. I can do something like this in the getView() method in the table adapter:

linearLayoutBusiness.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent i = new Intent(context, DetailsActivity.class);
            i.putExtra("business", business);
            context.startActivity(i);
        }
    });

What I have so far is this in the cellForRowAtIndexPath method:

    //business details tap handler
    UITapGestureRecognizer *touchOnBusinessDetails = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(detailsTapHandler)];
    [cell.BusinessInfoView addGestureRecognizer:touchOnBusinessDetails];


    //call view tap handler
    UITapGestureRecognizer *touchOnCallView = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(callViewTapHandler)];
    [cell.callView addGestureRecognizer:touchOnCallView];

    //location view tap handler
    UITapGestureRecognizer *touchOnLocationView = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(locationViewTapHandler)];
    [cell.locationView addGestureRecognizer:touchOnLocationView];


    return cell;
}

- (void)detailsTapHandler{

    NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
    NSInteger row = selectedIndexPath.row;
    BusinessEntity *businessTapped = businesses[row];

    //open details view
    [self performSegueWithIdentifier:@"detailsSegue" sender:self];
    NSLog(@"detailsView");
}

- (void)callViewTapHandler{
    NSLog(@"callView");
}

- (void)locationViewTapHandler{
    NSLog(@"locationView");
}

The problem I have run into is the selectedIndexPath is always nil, and I can't send the business object corresponding with the selected row in the detailsTapHandler method.

Am I on the right track? Or is there a better way to do this?

Upvotes: 0

Views: 69

Answers (1)

Alex Skalozub
Alex Skalozub

Reputation: 2576

Your selectors should look like:

- (void)locationViewTapHandler:(UIGestureRecognizer*)sender 
{
    NSLog(@"locationView");
}

So when selector gets triggered, it is passed gesture recognizer as an argument. Then you can use sender.view property to access view attached to the gesture recognizer.

Knowing the view, you can either crawl up the view hierarchy to get the UITableViewCell containing it, and then call [tableView indexPathForCell:cell], or just store model index in the view's tag property and access model directly by index.

Upvotes: 1

Related Questions