I'm trying to figure out from Apple's sketchy documentation which method is the best place to be initializing and adding my Views controls to the controller's view.
With winforms it's fairly straightforward, as they're always initialized inside InitializeDesigner
, called in the constructor. I'm trying to match the reliability of this pattern if possible.
I'm working with UIViewControllers
and UITableViewControllers
inside a UINavigationController
most of the time - if this effects it all.
Here's an example:
public MyController()
{
// Here?
AddViews();
}
public override ViewDidLoad()
{
base.ViewDidLoad();
// Or is should it be here?
AddViews();
}
public override ViewWillAppear(bool )
{
base.ViewWillAppear(animated);
// Here?
AddViews();
}
public override ViewDidAppear(bool animated)
{
base.ViewDidLoad(animated);
// Or maybe here?
AddViews();
}
void AddViews()
{
UILabel label = new UILabel();
label.Text = "Test";
label.Frame = new RectangleF(100,100,100,26);
View.AddSubView(label);
UIWebView webview = new UIWebView();
webview .Frame = new RectangleF(100,100,100,26);
View.AddSubView(webview);
}
I get mixed results with some UIControls when I add them to the view in different places. Visual lag sometimes, othertimes the webview is hidden somewhere.
Is there a general rule to keep to for adding them?
In general, this is what I do:
ViewDidLoad - Whenever I'm adding controls to a view that should appear together with the view, right away, I put it in the ViewDidLoad method. Basically this method is called whenever the view was loaded into memory. So for example, if my view is a form with 3 labels, I would add the labels here; the view will never exist without those forms.
ViewWillAppear: I use ViewWillAppear usually just to update the data on the form. So, for the example above, I would use this to actually load the data from my domain into the form. Creation of UIViews is fairly expensive, and you should avoid as much as possible doing that on the ViewWillAppear method, becuase when this gets called, it means that the iPhone is already ready to show the UIView to the user, and anything heavy you do here will impact performance in a very visible manner (like animations being delayed, etc).
ViewDidAppear: Finally, I use the ViewDidAppear to start off new threads to things that would take a long time to execute, like for example doing a webservice call to get extra data for the form above.The good thing is that because the view already exists and is being displayed to the user, you can show a nice "Waiting" message to the user while you get the data.
There are other tricks you can use, though. Lets say you want a UILabel to "fly" into the form after the form is loaded. In that case, I would add the label to the form in the ViewDidLoad but with a Frame outside of the view area, and then in the ViewDidAppear I would do the animation to fly it back into view.
Hope it helps.
Hmm, Apple's docs seem to be pretty clear, IMHO.
If you create your own root view (the root view of this particular controller's view hierarchy) programmatically, you should create it in -loadView
without calling super
and set the view
property when done. If your view is loaded from a nib, you should not touch -loadView
.
You add custom subviews to the view controller's view or otherwise modify it in -viewDidLoad
. The recommended practice is to create your UILabel and UIWebView in -viewDidLoad
and release them in -viewDidUnload
, setting their references to nil
if you need to keep them in ivars.
Note: -viewDidUnload
is deprecated in iOS 6 and is just not called any more, because UIViewController
no longer purges its view under memory pressure.
viewDidLoad relates to 'MEMORY', and viewWillAppear/viewDidAppear relates to 'APPEARANCE'. A view controller's view (which is a root-view of your view controller's views) can appear/disappear numerous times, even if the controller's view is already in memory.
(When referring to root-view, I also means its subviews, because the root-view has reference to its children (subviews), but from a view controller's perspective, it usually knows just the root-view. Reference to subviews can happens normally through view controller's outlets.)
The root-view itself MAY be removed from memory when there's a memory warning. The view controller will determine when is the best time to removed them from memory.
So, you would normally add subviews in viewDidLoad, because adding subviews means adding them to memory. BUT not if you create all of your views programmatically (not from a nib files). If that's the case then you should override loadView method, and create a root-view and add subviews there, so in this case you can omit viewDidLoad to add subviews.