Reputation: 18578
I'm diving into iOS development and I'm building a puzzle game to help me become familiar with the platform. I have AdWhirl displaying ads in the score screen that is displayed when the user completes a puzzle. The problem is, it takes at least a few seconds for the score screen view controller to request and receive the ad, in which time the user looks at the score and moves onto a different view. I'm planning to implement an animation that occurs when the user solves a puzzle and the time it takes for the animation to finish would be a good time to request and receive the ad that will be displayed in the next (score) view the user will be taken too.
During the time that the solved-the-puzzle animation is taking place, how can I preload the next view controller so that the ad is present when I push the view controller on to the navigation stack? If this isn't possible, or if it's a bad idea, do you have any suggestions for how I can request and receive the ad while the animation is taking place?
Thanks so much in advance for your wisdom!
Note: For those who aren't familiar with AdWhirl, the process of requesting and receiving an ad is simple. In the viewDidLoad method of the view controller you want the ad to appear in, you create an AdWhirlView (subclass of UIView), add it as subview, and call a method that requests an ad. When the ad arrives, it calls a delegate method to display it in the parent view.
Upvotes: 14
Views: 12192
Reputation: 13926
Two functions are available in iOS 5 and above.
Calling setNeedsLayout()
is like telling the system that you want to update the layout of the called views and sub-views and redraw them. Changes are not immediately reflected. As the name also includes, it simply sets the mark and reflects it in the scheduling. Changes can only be reflected in the view when the next update cycle is returned.
It is important that the task caused by the call of this method is performed asynchronously. Therefore, the developer does not know when the update cycle will come to reflect the change.
On the other hand, layoutIfNeeded()
is a synchronous call. They are asking the system to reflect the changes immediately. As the name suggests, layout is done immediately. Thus, the change is already reflected in the view by the time control is returned after the call of this method has been made.
Upvotes: 0
Reputation: 12839
In iOS 9 a new method was added loadViewIfNeeded()
. I believe it was originally intended for unit testing of view controllers, but it should work for this case as well.
Upvotes: 3
Reputation: 36003
Put this on your delegate's application:didFinishLaunchingWithOptions:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboard" bundle:[NSBundle mainBundle]];
[storyboard instantiateViewControllerWithIdentifier: @"TheViewControllerYouWantToPreload"];
});
The dispatch_async
will make the whole thing load in background.
Upvotes: 2
Reputation: 3398
There is a side effect with just using [viewController loadView] and that is that viewDidLoad will not be called automatically after the view has loaded.
To do it properly and to make sure that viewDidLoad gets called, instead of calling loadView yourself you can instantiate the UIViewController´s view using
UIView *view = myViewController.view;
or
UIView *view = [myViewController view];
This will both call loadView (if the view was not already loaded) and then viewDidLoad when the view has finished loading.
Upvotes: 31
Reputation: 45598
In response to the accepted answer, you must not call -loadView manually. From 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.
Instead you should just call [myViewController view] which will trigger the view to load.
As always, read the documentation!
Upvotes: 15
Reputation: 9113
You can call the loadView manually, I don't know if there are any side effect but I don't think so.
Thanks Tommy, indeed, accessing the view property ensure that loadView will only be effectively called only if the view hierarchy is not loaded yet, avoiding any potentiial leak if the loadView code does note cope with it.
Upvotes: -3