Make a view (initialized from initWithNibName) load all its subview
Asked Answered
S

2

9

Assuming I load a view controller from a nib, and decide to do something with one of its subview behind the scene. At a later moment in time, I would show the view of this view controller.

viewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; 
[viewController.someSubview doSomething];

//later on 
[mainView addSubview:viewController.view];

The problem is that, the someSubview object doesn't seem to be loaded until the view appears, so the method doSomething is not called. So far my workaround is to call:

[mainView addSubview:viewController.view];
[viewController.view removeFromSuperview];

to initialize the subviews of viewcontroller first. Is there any more elegant way (like a loadSubviews method or something) for this task?

Supercilious answered 20/12, 2009 at 11:8 Comment(0)
C
23

First of all I would try simply accessing the property:

[viewController view];

This will force the lazy load of the view (and thus the subviews and outlets etc.) and this might be enough for you. View controllers by default will not load their view until you access it so this might be why you are seeing a delay.

Forcing a load like this is usually the solution when you are trying to access an outlet property but it hasn't actually been bound yet, like someSubview in your case.

You can also improve things a bit by adding the view but making it hidden:

viewController.view.hidden = YES;
[mainView addSubview:viewController.view];

Then instead of calling addSubview when you want to show it, just do:

viewController.view.hidden = NO;

I've used this method when animating in views using the UIViewAnimationTransitionFlipFromRight etc. transitions. Even when forcing a lazy load of the view there is still a noticable lag, so I've used this to improve the performance a bit.

Coquina answered 20/12, 2009 at 11:28 Comment(2)
@MarkAmery Apple tells you explicitly not to call -loadView in the documentation: "You should never call this method directly. The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property."Coquina
@MikeWeller Good point - I hadn't looked at the documentation closely enough to know that. I guess we have to choose between one of two slightly ugly hacks, then. For my part, I'll probably stick to loadView just because it's more explicit, but I concede that it's not the clean solution I thought it was.Alard
K
0

iOS 9 introduced -(void) loadViewIfNeeded

I use

if ([_myVC respondsToSelector:@selector(loadViewIfNeeded)]) {
    [_myVC loadViewIfNeeded];
} else {
    [_myVC view];
}
Kraft answered 11/3, 2016 at 2:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.