Question

My application launches into a navigation controller. The root view controller has a button which creates a popover with a tableViewController allowing the user to select a cell which, using a delegate of the TableViewController that is set when the popover is created though 'preperaForSegue', communicates back to the root view controller and pushes the relevant ViewController onto the navigation stack.

Delegate set like this:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"planningSegue"]) 
    {
        [segue.destinationViewController setDelegate:self];
    }
}

Method called like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [[self delegate] gotoPlanningToPage:[tableView cellForRowAtIndexPath:indexPath].textLabel.text];
}

This much works fine.

I have another button on the root view controller which brings up a different popover with a different tableViewController, this one has a list of options each of which, when selected, will segue another table view onto the stack (still within the popover) containing a list of items. Selecting one of these needs to communicate back to the main ViewController (the one which created the popover initially) to push a new view onto its navigation stack similarly to how the first button does.

The question: How/where do I set the delegate for the second tableViewController?

I can't create it when the popover is created, because the second tableViewController only comes into existence when a cell is selected in the first TVC. But I can't work out how to set it from the first TVC when the second TVC is being called because I don't see a way to be able to communicate back to the creator (parent?) of the popover.

The only thought I've had is to set the main ViewController to be a delegate for the first level TVC in the popover, then setting that TVC to be a delegate to the second level TVC and passing a message back through one, to the other... That just doesn't sit right though, I can't help but thing that there must be a simpler/cleaner way to do it rather than creating a delegate with the sole purpose of helping something else set its delegate!

I'm still relatively new to all this, so apologies if I haven't made sense or if I've missed something glaringly obvious!

Was it helpful?

Solution 2

Whether or not this is the best way, I'm not sure, but it seems to be working and setting the delegate just fine. I've put the following in prepareForSegue in the popovers first tableViewController,

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell *)sender
{
    SecondLevelTVC *secondLevelTVC = (SecondLevelTVC *)segue.destinationViewController;
    UINavigationController *mainNav = (UINavigationController *)self.view.window.rootViewController;
    RootAppViewController *rootAppViewController = (RootAppViewController *)mainNav.topViewController;
    secondLevelTVC.delegate = rootAppViewController;
}

OTHER TIPS

Your idea is mostly correct. You can set the main ViewController to be a delegate for the first level TVC as you say. Then, since your first level TVC already has a reference to the main viewController you can use that to set the second level TVC's delegate property at the time you instantiate it (when the table row is selected).

So in your first level TVC:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    SecondTVC *secondTVC = [[SecondTVC alloc] init];
    secondTVC.delegate = self.delegate;
    [self.navigationController pushViewController:secondTVC animated:YES];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top