Reputation: 16317
I have a custom UITableViewController
with 2 properties:
@property (strong, nonatomic) IBOutlet VenueHeaderViewController *header;
@property (strong, nonatomic) IBOutlet VenueFooterViewController *footer;
The UIView
s of my VenueHeaderViewController
and VenueFooterViewController
were designed in IB. Each of these controllers has IBOutlet
s to its subviews as set up in the storyboard. This is my storyboard:
My question is, how do I now connect my header
and footer
IBOutlet
s inside my UITableViewController
to instances of my VenueHeaderViewController
and VenueFooterViewController
while retaining the layout and IBOutlet
s which I have set up in the storyboard?
Upvotes: 4
Views: 1524
Reputation: 126167
You can't hook up IBOutlets across different scenes in a storyboard. Scenes are each entirely self-contained, and only connected via segues (or relationships in the case of special container view controllers like tab, navigation, split view and popover controllers). If you've done any IB work without storyboards, think of each scene (view controller) as being in its own nib (in fact, that's what storyboards do behind the scenes).
Beyond that, it's generally the case (on iPhone at least) that there's a one-to-one mapping between a view controller and a "screen" of UI -- you generally don't have different view controllers managing different parts of the screen, as appears to be the case with the header, table, and footer you have. (Thus, you'll pretty much never have an IBOutlet to any UIViewController
subclass.)
So what can you do? Here's a few different approaches, from easier to harder:
If you're meaning to assign those header & footer views to the UITableView
's tableHeaderView
and tableFooterView
properties, you can do that in the storyboard in IB -- just drag a UIView of some sort from the library toward the top or the bottom of the table until you see a blue line above or below the prototype cell(s):
The table header & footer views might or might not be what you're after, though: they're part of the scrolling content of the table (that is, they appear above the first row and below the last, respectively, so they can be scrolled off the screen).
If your intended use of these views is as "header" and "footer" in that they always appear above or below the table regardless of where it's scrolled, then what you really need is to have the header, footer and the table view all be subviews of a root view.
For that, you'll need a regular UIViewController
subclass rather than a UITableViewController
subclass. You can put a UITableView
in as a subview of that view controller's root view, and arrange whatever other views you want to be visible above/below it. (Just make sure to set the autoresizing sensibly if you plan to support rotation.) Here's an example:
(If you're wondering where the prototype cells are when you first drag out the table view, check the inspector -- you set the number of them in the upper right of that screenshot.)
With regular nibs (not storyboards), you can set up views in IB which aren't the view controller's root view. Then you can still connect outlets to them, and programmatically insert them into the view hierarchy as needed.
You can sort of do this in a storyboard, too -- drag views to the black bar beneath the scene -- but due to a bug in the current version of Xcode, you can't see these views for editing. Oops.
If none of the above suit your needs, you might still have a use for multiple view controllers -- say, if you wanted to switch out different different header views at various times, and save memory by dynamically instantiating these view hierarchies as needed. Cases like this are pretty rare, though... you should make sure you've exhausted other options first.
In effect, you're still using one of the previous two approaches, but the views you want are located in other scenes (again, it's like they're in other nibs). Here, the view controllers holding the other views don't even need to be custom subclasses of UIViewController
, since they're just temporary containers for views you want to insert into a different view controller's view hierarchy.
In that case, the storyboard you have is what you want... it's just a matter of getting those view controllers appropriately loaded, which you can do thusly:
SpecialViewController *svc = [storyboard instantiateViewControllerWithIdentifier:@"SpecialViewController"];
Then, pull the view
property from each view controller, insert it into your "main" view controller's view hierarchy, and dispose of the the view controller you pulled it from.
Upvotes: 5