Storyboard relationship in iOS

11,600

Solution 1

The way I understand it is: relationships are iOS's way of representing a 'parent-child' relationship and while that does seem quite recursive, an example of parent-child relationship is a UIViewController Container containing a UIViewController.

That's the theory anyway -- it's better understood using the UINavigationController. It is called a 'container' because it contains as many regular UIViewControllers in a 'stack' metaphor so you can do your normal UITableView drill downs and pop offs.

The key point is that the segue between UINavigationController and the first UIViewController in your stack, there is a 'relationship' while the segue between all the rest of the UIViewControllers is just a regular push segue.

The same thing is evident in the UISplitViewController -- it needs two view controllers (sometimes called content view controllers) from launch and these are connected up between the parent UISplitViewController (the container) and two regular (content) view controllers

(thus relationships are not like IBOutlets, but more like segues -- they are even in the 'segues' category of the standard view controller containers)

Now - we aren't allowed to subclass the standard view controller containers, but we are allowed to create custom view controller containers, but I can't for the life of me define a relationship in my custom view controller container!!!!!!!!!!!

so: "can I use them in my own controllers?" the answer is yet unknown (to me at least, and the documentation is thin at best)

Solution 2

Create a subclass of the UIStoryboardSegue like this:

@implementation JTARelationshipSegue

- (void)perform
{
  return;
}

@end

Make a custom segue between your two objects and set the class as JTARelationshipSegue. In your view controller make the view controller perform the segue like this:

- (void)viewDidLoad
{
  ...
  [self performSegueWithIdentifier:@"addChild" sender:self];
}

You need to have set the segues identifier in interface builder to addChild.

Impement prepareForSegue:sender so that it adds the segues destination view controller as a child of the current view controller, like this:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
  UIViewController *destination = [segue destinationViewController];
  [self addChildViewController:destination];
  ...
}

You will need to have a different segue identifier for each child that you want to create (or another way of identifying the specific view controller.

This will make your storyboard file look prettier, and more readable, however you may do better to just load your other view controllers and add them as children in your view did load method:

- (void)viewDidLoad
{
   [self addChildViewController:
         [[self storyboard] 
          initiateViewControllerWithIdentifier:@"myIdent"]];
...
}
Share:
11,600
Jonathan.
Author by

Jonathan.

I'm a 25 year old Software engineer in London, proudly working on the Elfin Market iOS app. I've made a few tweaks for jailbroken iOS and some other stuff.

Updated on July 28, 2022

Comments

  • Jonathan.
    Jonathan. almost 2 years

    I'm attempting to use the new Storyboard feature, however I am confused about Storyboard Relationships? How are they different to IBOutlets?

    Also how can I add my own relationship, to my own UIViewController subclass?

    I have tried looking in the documentation but can't find much about them.

  • Jonathan.
    Jonathan. over 12 years
    so how is that different from an IBOutlet? And how can I use them in my own controllers?
  • Simon
    Simon over 12 years
    When you create a segue, it allows you to specify an identifier. You use that identifier to check whether that segue is currently being used to transition from one controller (or whatever) to another. You don't really use them in any other way - so they differ from IBOutlets in that respect. They are also used to identify how to push the new view (push / modal / popover etc). The tutorials I linked show how to use them in your own controllers.
  • cynistersix
    cynistersix over 9 years
    Thats pretty clever though it doesn't seem 100% the right way to use a segue. I don't think UINavigationController does this to expose the rootViewController relationship... but who knows.
  • cynistersix
    cynistersix over 9 years
    This totally works and I'm now wiring up connections in my storyboard for easy readability with your method.
  • Simon
    Simon over 8 years
    Updated links to the tutorial, recently broken after site move. I'm assuming this is the reason for the unexplained / unreasoned down-voting.