OneManBand OneManBand - 3 months ago 12
iOS Question

Implementing delegation between views embedded in two separate container controllers

The relevant part of my storyboard appears as follows:
http://imgur.com/09livAb
You can see the custom "Container Controller" view houses two Container Views, one which links to a Navigation Controller via embedded segue, and another that links to a custom "Master View Controller" (which implements a Table View Controller) via embedded segue. The Navigation Controller component further has a relationship with a custom "Location Filter Controller."

I need to implement delegation such that when one of the UISteppers in the Location Filter Controller is incr./decr., the table view in the Master View Controller knows to update the data it displays accordingly.

I am not unaccustomed to working with protocols/delegates, but this unique situation of talking between views housed in segues is really tricking me! For the most part I have had success following the example here: Passing Data between View Controllers. In this case however, I am not able to directly link instantiated views as he indicates to do in 'Passing Data Back' step 6.

I had considered using a singleton object from which each of these views could get/set the necessary data, but the issue here is that the table view would not necessarily know when to update its contents, despite having data with which it could/should update.

Here is a code snippet from ContainerController.m where I setup the embedded segues to function:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DataHold *data = [[DataHold alloc] init]; // <-- this actually is a singleton object

if([segue.identifier isEqualToString:@"locationEmbedSegue"])
{

}
else if([segue.identifier isEqualToString:@"tableEmbedSegue"])
{
[[segue destinationViewController] setDelegate:data.detailTableViewController];
// ^ This part actually sets up a delegate so that the table view (Master View Controller)
// delegates to the detail view controller of the overarching split view controller
// and tells it what to display when a row is pressed.
}
}


Thanks for any help!

Answer

I think you are on the right track setting the table view delegate to your Location Filter Controller.

I found that a simple way to work with embeded view controller is to add "placeholders" property for them, and set these property when the segue is "performed".

// MyContainerController.h
@property (strong, nonatomic) MyLocationFilterController *detailViewController;
@property (strong, nonatomic) UITableViewController *masterViewController;

// MyContainerController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"locationEmbedSegue"])
    {
        UINavigationViewController *dest = (UINavigationViewController *)segue.destinationViewController;
        self.detailViewController = dest.topViewController;
    }
    else if([segue.identifier isEqualToString:@"tableEmbedSegue"])
    {
        self.masterViewController = (UITableViewController *)segue.destinationViewController;
        [self.masterViewController.tableView setDelegate:self.detailViewController];
    }
}
Comments