Should we call ads in viewDidLoad or viewDidAppear? - objective-c

We have a tab-heavy app, which has 5 tabs to use back and forth. We have iAds and admobs(as backup for countries without iAd), and we 'call' the ads in viewDidLoad. Would it make a difference to call them in viewDidAppear instead? And then remove them in viewDidDisappear or shomething not to screw up the frames etc? Would this give more impressions etc?

viewDidLoad:
viewDidLoad
Called after the controller’s view is loaded into memory.
- (void)viewDidLoad
Discussion
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
viewDidAppear:
viewDidAppear:
Notifies the view controller that its view was added to a view hierarchy.
- (void)viewDidAppear:(BOOL)animated
Parameters
animated
If YES, the view was added to the window using an animation.
Discussion
You can override this method to perform additional tasks associated with presenting the view. If you override this method, you must call super at some point in your implementation.
Answering
So viewDidLoad is called slightly earlier than viewDidAppear: , the only difference is that when viewDidAppear: the view have been already drawn, instead in viewDidLoad the view has still to be drawn.
So answering to your questions:
Would it make a difference to call them in viewDidAppear instead?
If calling the ads is a slow operation, then you would see first the view appearing in it's color, and the ads after a few interval of time.However this has to be too slow to make a real difference.
And then remove them in viewDidDisappear or shomething not to screw up the frames etc?
It doesn't "screw up frames", that for sure.

you just need call it in viewDidLoad

Putting your ad code in viewDidAppear: (and removing it in viewDidDisappear:) will certainly give you more impressions, but unless you're a whitelisted pub, you're probably getting paid on a cost per click basis anyway (AdMob Help Center article).
In this case, instead of having the overhead of creating and destroying GADBannerView objects on tab changes, you might as well create a singleton GADBannerView that you use throughout your TabbedController (look at an example here).

Related

When will viewWill/DidAppear/Disappear is called anyway and how exactly does it work?

I understand that viewWillAppear will be called when duh.... when the the view is about to appear.
But how does IOS know that a controller's view is about to appear?
When exactly that and how it is implemented?
For example, does the childController.view check first that window is one of it's super ancestors? Does the view has a pointer to it's controller? How exactly that works? Does everytime a view is added it check whether it's window is it's super ancestor and whether it is the view outlet of a UIViewController?
For example, if I add childcontroller.view but not to a subview of any view that's being called. Will viewWillAppear called?
Does the childController need to be the a child of a parentController so that viewWillAppear of the childController will be called when the parentController's viewWillAppear is called automatically?
The view is loaded by your controller using the - (void)loadView method. This method is implemented to load a blank view or a view from a nib/storyboard. You only need to override it if you really need to create a view hierarchy from scratch.
All of the magic happens when the value of the view property is first requested and the controller detects the value is nil. All of the life cycle method calls are handled by the UIViewController. There is nothing you need to do other than implement the methods if you need them. Remember one thing: There is no guarantee the view has been loaded until the - (void)viewDidLoad method has been called.
Everything I've learned about controllers how they work has come from the View Controller Programming Guide.

What is called when removing a view from its superview?

Imagine I have a view controller called blueView and another called greenView. I then add greenView.view as a subview of blueView.view. Now suppose that after some user interaction, I'd like to remove greenView.view from blueView.view using:
[self.view removeFromSuperview]
What is actually happening here? Is blueView.view ever redrawn? I thought the viewDidLoad method might be called, however after putting an NSLog messge in viewDidLoad, it was never called after removing the subview. Any clarification as to what is actually happening when you remove a subview from its superview would be much appreciated.
First, a view controller is meant to manage an entire view hierarchy at once; you shouldn't have two view controllers (other than container controllers like UINavigationController) active at the same time. See this SO question and my answer to get a better understanding on this important point. So, the particular situation you describe shouldn't come up. (Aside: people often confuse views and view controllers, so it's not helpful to give your view controllers names ending in "-view", like "blueView." Call it "blueViewController" to help avoid confusion.)
Second, as #InsertWittyName points out, -viewDidLoad is a UIViewController method, not a UIView method. Taking that a step further, neither view controllers nor -viewDidLoad has any role in adding or removing subviews from a view. -viewDidLoad is called when the view controller's view is first created. It's basically just a way of deferring the view-related part of view controller initialization until after the view hierarchy has been created, so there's no reason that it'd be called again just because a subview was removed from the hierarchy.
Finally, exactly how a view removes itself from its superview is really an implementation detail -- it might call a private UIView method on the superview, or it might modify the superview's list of subviews directly, or something else. I don't see anything in the documentation that explicitly says that the superview will redraw itself after a subview has been removed, but in my experience the superview does indeed redraw itself. You can check this by putting a breakpoint on the -drawRect method of the superview.

View Controller inside View Controller won't receive rotation messages - ios

I have a customized View Controller (we'll call it the wrapper). Its view contains only a UIScrollView. The scroll view contains another customized view controller (we'll call it the inside view), initialized from an xib file (the scroll view itself is initialized from a xib file as well, but I don't believe it matters).
The wrapper view is displayed using a UITabBarController, which contains several more similar view controllers.
I have this weird problem: the wrapper's rotation functions - shouldAutoRotate, willAnimateRotation - get called every time that I rotate the device. For some reason, the inside view's rotation functions don't get called, but it still rotates. The inside view's shouldAutoRotate does get called when initializing it (when the app starts).
I've looked at google and couldn't find anything that is relevant to my case. I'm not sure if it is related, but the Autoresize subviews is checked on all xib files.
I'd be glad if you could help me solve this problem. I need the inside view's rotation function to get called on rotation in order to arrange it manually, but I'd like to avoid calling them from the wrapping view (rather it to work as it should).
Thank you in advance!
Well the innerViewController's rotation function will not be called because they are added as subview's to your scrollView what you can do is generate a NSNotification when orientation changes in your parent controller then you can receieve notification in subview and manage them accordingly. Or you can iterate through subviews of UIScrollView when your shouldAutoRoatate called in you parent controller and then manually call should autorotate method of child views. Hope you understand.
The simplest way is to hold some UIInnerViewController* innerController in your .h file and in .m to call inner's
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation inside of the wrapper like so:
wrapper.m
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
BOOL innerResult = [innerController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
//may be more computations here
return innerResult;// or any other value, based on your needs
}
Other approach that you may use is to register inner controller to UIDeviceOrientationDidChangeNotification like so:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
and layout subviews in -(void)orientationChanged:(NSNotification*)notification;in the same inner controller. The only thing you should be awere of, is that UIDeviceOrientation is a little-bit different than UIInterfaceOrientation and may hold value such UIDeviceOrientationFaceUp that is not applicable to UI changes in most cases.
Nesting viewcontrollers inside custom viewcontrollers is not supported in iOS 4. You can usually forward all the necessary messages to your child VC's manually, though, with acceptable results.

Modal view controllers calling other's "viewDidLoad"

I have a bunch of pages I am chaining together and presenting as modal view controllers. THey all have viewDidLoad methods. It seems that when one is loaded though it calls the viewDidLoad methods of ones in the background too. How can I stop this? Thanks!
You can't. The viewDidLoad method will get called when the view is loaded. Asking a view controller for its view loads the view.
Consider moving code into your viewWillAppear:(BOOL)animated method. That way it will only get called before the view is actually shown to the user.

UIWindow and UIView addSubview Question

Does the addSubview method actually load the view into the application or not? The reason I am asking is because I have two two views in my application. The application delegate adds the two views as subviews and then brings one of the views up front. Now, I have a print statement in each of the viewDidLoad methods for each view. When I run the application, the application delegate loads the views as subViews and as each view is loaded, I actually see the console print out the statements that I placed in each of the viewDidLoad methods. Is this supposed to be doing this?
viewDidLoad is actually a method of UIViewController, not UIView. It gets called after the view gets loaded into memory (after your init method, but before the awakeFromNib). You'll notice that addSubview: takes a UIView as a parameter, so the view must have been loaded in order for the view to be added to another view. Otherwise you'd be trying to add an imaginary view.
In answer to your question, yes it is supposed to be doing this. viewDidLoad is called long before you addSubview. In fact, if you take out the addSubview: lines, you'll notice that it's still getting called (because you're creating the view's controller).
My understanding is that views are lazily loaded. If your viewcontroller has 10 view, they are not all loaded until you actually try to access them.