views:

1872

answers:

2

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?

+2  A: 

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.

Costique
Thanks I missed that method. However I still feel the methods I listed give very limited info of when to use them. Even in loadView all you're told is *'If you want to perform any additional initialization of your views, do so in the viewDidLoad method'* - when would you ever need this method?
Chris S
loadView is the method which either loads the view hierarchy from NIB or just creates an empty UIView if there's no NIB to load. You may want a custom view instead of it, in which case you override loadView. UITableViewController, for example, overrides this method to create a UITableView. I often find myself doing the same thing with my own UIView subclasses.
Costique
+7  A: 

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.

Eduardo Scoz
Thanks that's cleared a lot up. I haven't been able to add anything with the LoadView example from this question: http://stackoverflow.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload - do you ever use this method?
Chris S
So basically loadView is a method from the UIViewController (Use the rosetta stone when you're trying to figure these things out - http://tirania.org/tmp/rosetta.html). The framework automatically calls this method in the controller to tell it to create views, and the default implementation of the UIViewController then calls the ViewDidLoad. Although you can override this method (and make sure you call the base method when you do), personally, I prefer to to just use the viewWillLoad (called before loadView) and viewDidLoad (called just after).
Eduardo Scoz