peakingcube
peakingcube

Reputation: 1418

iOS - Why setting and displaying subviews in initWithNibName doesn't work?

I have a simple xib file which its layout is:

enter image description here

Which the pale green UIView is referenced to an IBOutlet view_content in my UIViewController class. Then I did the following in initWithNibName:bundle: of my ViewController.m:

self = [super initWithNibName:nibNameOrNil bundle:nil];
if (self) {

    self.view_a = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    self.view_a.backgroundColor = [UIColor purpleColor];
    [self.view_content addSubview:self.view_a];

    self.view_b = [[UIView alloc] initWithFrame:CGRectMake(150, 150, 100, 100)];
    self.view_b.backgroundColor = [UIColor blueColor];
    [self.view_content addSubview:self.view_b];

    self.view_c = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
    self.view_c.backgroundColor = [UIColor greenColor];
    [self.view_content addSubview:self.view_c];

}
return self;

I expected there will be 3 small squares, each with different colors as declared in the code above, but they did not show up which the view is loaded and showed. But instead if I move the addSubView: calls into viewDidLoad, they are displayed as expected. I tried to test if view_content is nil in the if-segment and seems it is nil at that time. I don't understands why this is happening and how it works, isn't the view and its components are supposed to be loaded from the xib?

Thanks for any help!

Upvotes: 0

Views: 262

Answers (2)

Atif
Atif

Reputation: 1220

The reason is simple. View is not loaded at that time when you are initializing the controller means initWithNibName. So best place is viewDidLoad where your all outlet has been assigned.

Upvotes: 0

Khanh Nguyen
Khanh Nguyen

Reputation: 11134

At the point initWithNibName:... is called, the view itself is not yet loaded. This is an optimization (lazy loading) that defers loading the view until it is actually needed. The view is actually loaded when viewController.view is first-time accessed, and that's when viewDidLoad is called.

Some people force the view controler to load its view by calling [viewController view] (or [self view] if it's within the view controller's class).

Upvotes: 1

Related Questions