Search code examples
objective-ccontrollersuperview

How to get a reference to the view controller of a superview?


Is there a way to get a reference to the view controller of my superview? There were several instances that I needed this on the past couple of months, but didn't know how to do it. I mean, if I have a custom button on a custom cell, and I wish to get a reference of the table view controller that controls the cell I`m currently in, is there a code snippet for that? Or is it something that I should just solve it by using better design patterns?

Thanks!


Solution

  • When I asked this question I was thinking of, in a situation where I have custom cells with buttons on them, how can the TableViewController know which cell's button was tapped. More recently, reading the book "iOS Recipes", I got the solution:

    -(IBAction)cellButtonTapped:(id)sender
    {
    NSLog(@"%s", __FUNCTION__);
    UIButton *button = sender;
    
    //Convert the tapped point to the tableView coordinate system
    CGPoint correctedPoint = [button convertPoint:button.bounds.origin toView:self.tableView];
    
    //Get the cell at that point
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:correctedPoint];
    
    NSLog(@"Button tapped in row %d", indexPath.row);
    }
    

    Another solution, a bit more fragile (though simpler) would be:

    - (IBAction)cellButtonTapped:(id)sender 
    {
        // Go get the enclosing cell manually
        UITableViewCell *parentCell = [[sender superview] superview];
        NSIndexPath *pathForButton = [self.tableView indexPathForCell:parentCell];
    }
    

    And the most reusable one would be to add this method to a category of UITableView

    - (NSIndexPath *)prp_indexPathForRowContainingView:(UIView *)view 
    {
       CGPoint correctedPoint = [view convertPoint:view.bounds.origin toView:self]; 
       return [self indexPathForRowAtPoint:correctedPoint];
    }
    

    And then, on your UITableViewController class, just use this:

    - (IBAction)cellButtonTapped:(id)sender 
    {
        NSIndexPath *pathForButton = [self.tableView indexPathForRowContainingView:sender];
    }