Search code examples
iosdelegatesuisplitviewcontroller

Assigning Delegation for a splitViewController where the masterController is housed in a Container View


I need help programmatically traversing a storyboard hierarchy. This image should give some context: storyboard. The hierarchy consists of a splitViewController for which the master is a tabViewController with three tabs. The first tab contains two container views, the lower view being the 'problem child'.

I have had success traversing the hierarchy and assigning to the detailViewController the masterViewController as a delegate for tabs 2 and 3:

UISplitViewController *splitViewController = (UISplitViewController *) self.window.rootViewController;
    UITabBarController *masterTabBarController = [[splitViewController viewControllers] objectAtIndex:0];
MasterViewController *masterViewController2 = [[masterTabBarController viewControllers] objectAtIndex:1];
MasterViewController *masterViewController3 = [[masterTabBarController viewControllers] objectAtIndex:2];
masterViewController2.delegate = detailTableViewController;
masterViewController3.delegate = detailTableViewController;

However, tab 1 has been more irksome because of the container views. My attempt has not worked and results in an index-out-of-bounds error:

UIViewController *containerViewController = [[masterTabBarController viewControllers] objectAtIndex:0];
MasterViewController *masterViewController1 = [[containerViewController childViewControllers] objectAtIndex:1];
masterViewController1.delegate = detailTableViewController;

So instead of the AppDelegate, I've also tried two other routes within my MasterViewController itself:

- (void)viewDidLoad
{
    self.delegate = (DetailTableViewController *)[[self.splitViewController.viewControllers lastObject] presentedViewController];

//self.delegate = [[self.parentViewController.parentViewController.parentViewController.childViewControllers objectAtIndex:1] objectAtIndex:0]; Granted this should ONLY work for tab 1...but it doesnt.
}

But the uncommented line returns nil...

So I am hoping that some kind soul understands container views (as there is surprisingly little detail about these to be found) and how to access and assign a delegate to them via traversal, or some other technique. There has to be a better way - what I have here is a very small app; I can't imagine having to individually walk the hierarchy of a complex app with dozens of screens.

Thanks in advance!!


Solution

  • In attempt to find a solution to my problem, I tried to mimic my issue on a smaller scale in a brand new storyboard, making sure that all connections and code were set up appropriately. Then it dawned on me as I was setting up the container views:

    In storyboard, container views are automatically defined as "embed segues" and are not technically related to the screen in which they are housed. Therefore, you cannot simply ask for the children of the 'parent' view and expect to get back an array of the container views.

    So in order to pass data into and to define a delegate for the container views in question, I made a custom class for the view that housed the container views and ignored AppDelegate altogether. In this class I defined a prepareForSegue function:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        SingletonObject *data = [[SingletonObject alloc] init];
    
        if([segue.identifier isEqualToString:@"containerView1SegueID"])
        {
    
        }
        else if([segue.identifier isEqualToString:@"tableEmbedSegue"])
        {
            MasterViewController *masterViewController0 = segue.destinationViewController;
    
            [[segue destinationViewController] setDelegate:data.detailTableViewController];
            // ^ Or more specifically, 'masterViewController0.delegate = data.detailTableViewController;' would also work
        }
    }
    

    I hope this can help anyone who is having trouble with container views. They are not children! They are embed segues. Use prepareForSegue and you will be happy.