Usman Mutawakil
Usman Mutawakil

Reputation: 5259

Adding a header view to every view in an application

I have a header that I would like to add to every view in my program. Rather than manually do this I've been trying to find a way to insert this "header view" above every view that gets loaded. In the sample below, I tried using the insertSubView method but this inserts the entire view and not just the tiny bit of header content I'm interested in.

[self.view insertSubview:self.headerController.view aboveSubview:self.indexController.view];
[self.view insertSubview:self.indexController.view atIndex:0];   

Does anyone know how to do this correctly? I'm using Xcode 5.

Upvotes: 0

Views: 154

Answers (3)

Rufel
Rufel

Reputation: 2660

I'd suggest to create a base view from which you will subclass for every views that need this header.

You could have a BaseView.h that would look like:

@interface BaseView : UIView
@property (nonatomic) UIView *someHeaderView;
@end

And the implementation (.m) looking like this:

@implementation BaseView
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(frame), 150.0)];
        [self.view addSubview:self.headerView];
    }
    return self;
}
@end

Then have every views that requires a header subclass it:

@interface SomeViewRequiringHeader : BaseView
@end

Upvotes: 0

Rob
Rob

Reputation: 437917

You're inserting the views of the headerController and indexController on your other view controllers' views. Generally, though, you want to be careful about keeping your view hierarchy synchronized with your view controller hierarchy. The importance of this is discussed in some detail in WWDC 2011 video Implementing UIViewController Containment.

So, generally you'd instantiate the appropriate indexController and headerController, call addChildViewController, add the subviews, and then call didMoveToParentViewController for each of those two view controllers. For more information, see Creating Custom Container View Controllers section of the View Controller Programming Guide for iOS. But you app's view controllers might do something like:

HeaderController *headerController = ...                       // instantiate however is appropriate
[self addChildViewController:headerController];        
headerController.view.frame = [self frameForHeaderController]; // define the frame/constraints as appropriate
[self.view addSubview:headerController];
[headerController didMoveToParentViewController:self]; 

You'd then repeat that process for the indexController.

Just make sure to (in addition to doing the custom container calls) either set the frame of the view controller's frame or define auto-layout constraints that will dictate the placement of the view (like you do for any programmatically added view). If you don't specify the frame, it may well end up being CGRectZero, which is obviously not what you intended.

You might, though, consider flipping this around. Make a custom container view controller that includes your header and any other UI elements that persist for every view. Then make your app's view controllers as child controllers of that container "parent" view controller. If either the header controller's view or the index controller's view navigates your app between various content view controllers, this sort of structure might make more sense.

I think if you watch that WWDC video and/or review the Creating Custom Container View Controllers, this will make more sense.

Upvotes: 1

Snowman
Snowman

Reputation: 32071

Try reversing the order of the two:

[self.view insertSubview:self.indexController.view atIndex:0]; 
[self.view insertSubview:self.headerController.view aboveSubview:self.indexController.view];

Also, since headerController is a UIViewController, it probably has a nib file with a default size of full screen. If you want to only be a certain height, you have to modify that nib file with the appropriate height.

Upvotes: 0

Related Questions