This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
initWithNibName VS viewDidLoad
I'm new at iOS development. I would just like to know the main differences between these 2 functions ?
Thanks for your help
viewDidLoad
Is called when the view loads and is initiated/Unarchived and loaded into the memory. This is a great customisation stop.
initWithNibName:
Is used for initializing a certain class ( it is an overriden init method) with a xib file's name, the bundle parameter specifies the location of the file, you would pass nil for the main bundle, which is the projects folder.
You should set up your properties in the viewDidLoad. The initWithNibName: is something that you call when you create a controller instance from a nib File. I wouldn't put customisation code there.
viewDidLoad:
viewDidLoad is a part of iPhone application life cycle.This method is called after the .xib file is read and the outlets and actions are connected to your view controller. In this Method you can do assignment with your outlets. This method get called as many times as your view get Loaded and unloaded.
initWithNibName:
This method is the designated initializer for UIViewController classes. It's used whenever you're creating a UIViewController object in the code. This method sets up UIViewController to be able to load a nib on demand. This method is helpful when you are performing something different logic in init method.
Related
This question already has answers here:
`[super viewDidLoad]` convention
(2 answers)
Closed 9 years ago.
As in the title, I was wondering what is the "default" implementation of viewDidLoad in UIViewController? Does it really do anything? Also does it matter if in my UIViewController's subclass I write
-(void)viewDidLoad{
[super viewDidLoad];
/*custom code here*/
}
or
-(void)viewDidLoad{
/*custom code here*/
[super viewDidLoad];
}
?
P.S. This is not a duplicate, in other questions people ask when should they call [super viewDidLoad], while my main concern is what the UIViewController's implementation do with it.
That implementation does nothing, and can safely be removed if you have no setup to do after the view loads. However, it is fairly rare to have no custom setup to do here; this is the place where your view controller is telling you that all of its UI objects are available to customize with data. It's included in the template with an empty implementation as a reminder: here's where to do this.
As far as when to call super: the general expectation is that setup or initialization methods call super before doing work, and teardown methods call super after doing work.
ViewDidLoad Method Called after the controller’s view is loaded into memory.
This is where you want to instantiate any instance variables and build any views that live for the entire lifecycle of this view controller. However, the view is usually not yet visible at this point
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.
For detail Information
I have a main window which has the UITabViewController as its root controller. I am using a nib file for this. In Interface Builder, two of the tabs have been wired to Controller_A, Nib_A and Controller_B, Nib_B but the 3rd tab only knows about Controller_C.
I assumed that this would mean that the loadView method of Controller_C would be automatically called since I haven't bothered to specify the NIB file. I want to lay this piece out programmatically. And it DOES indeed get called as I've confirmed by placing a breakpoint inside this method.
BUT when I switched over to Controller_C in the simulator, it comes up empty!
Here's what the loadView of Controller_C looks like:
- (void)loadView
{
[super loadView];
...
[self setTableView:formTableView];
[view addSubview:formTableView];
[self setView:view];
}
Any tips? What am I ignoring?
Looks like you are searching for:
-(void)viewDidLoad {
Here are the main things to check.
Click on your Controller_C in interface builder. In the Identity Inspector, make sure that the Class field is set to Controller_C.
In the Attributes Inspector, make sure the NIB Name field is blank.
If you have an existing Controller_C.xib laying around in your project, remove and delete it. The default implementation of loadView loads this file even if
Remove [super loadView]. Since you're building your view hierarchy in code, you shouldn't invoke the default implementation. You should explicitly allocate the controller's view as a local variable in loadView and set it using setView:.
Also, your comment on the other answer suggests that you may be confused about when/why loadView and initWithNibName:bundle: get called, so let me clarify:
loadView gets called to lazy load your controller's view the first time its view property gets accessed. This is true whether your view controller was constructed as an object in a NIB, or whether you constructed it yourself in code using initWithNibName:bundle:. The default implementation of loadView loads the NIB that was specified in initWithNibName:bundle: or in the NIB Name property in IB. If a NIB name wasn't specified, the default implementation looks for any NIB in the bundle that has the same name as your class and loads that NIB if one is found. If no appropriate NIB is found, then the default implementation of loadView just creates an empty view and sets that as your controller's view. When we build our own view hierarchy explicitly in loadView, we don't want any of these default behaviors, so we don't call [super loadView].
It seems loadView works as expected, the reason that my view was blank is because the datasource for my tableview was actually NIL. Earlier, I did not consider this scenario as I thought that it would at least present an empty table in such a case but apparently that was an incorrect assumption on my part. All this mistakenly led me to believe that the view wasn't being initialized properly.
#cduhn: Thanks, I had been following steps 1-3 already and it was really good to hear someone else give the same advice. The rest of what you said was educational for me as well.
Thanks Everyone.
I'm having this problem because I originially made everything in the main NIB, but then after reading learned that it is better to use subviews.
I've got my IBActions in the AppDelegate, and I've successfully connected and loaded my subviews. However, when I try to connect my buttons in the subviews to the IBActions in the AppDelegate, the IBActions appear under the "First Responder". They seem to connect fine, but when running the application they do not trigger the IBActions (I've confirmed this with some NSLogs, it's not an error in the code within the IBActions). What am I doing wrong?
Thanks!
The AppDelegate should only be used for very specific items such as implementing the UIApplicationDelegate protocol (i.e. methods like applicationDidFinishLaunching) or in some cases storing global variables.
You should keep IBActions and other outlets in their respective view controller files (i.e. if you created MyViewController.h and MyViewController.m which are linked with MyViewController.xib where you have some buttons, images, etc.). They can then be hooked up via dragging the inspector control you want (i.e. TouchUpInside) to the File's Owner.
Something you should read to better understand view controllers: http://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html
Typically it is best to create a unique view controller for each view you will present to the user. For instance, if I had a main screen and then an "about" or a settings screen, I would make each of those their own view controller. It helps organize things better than using one view with a whole bunch of subviews that you hide/show and will also improve loading times and general performance.
Update for your 2nd question in the comments about accessing the app delegate:
First, you need to import the .h file (i.e. #import "AppDelegate.h") for the app delegate into whichever view controller .m file you wanna use to access whatever variables, arrays, etc you have stored in the app delegate files. Make sure you synthesize whichever objects you create in the app delegate's .h file in the app delegate's .m file so the getters and setters are created (so you can access them).
Then in the view controller .m file, in whichever method you are using:
-(void)someMethod {
// here we just create a shortcut to the app delegate called "theAppDelegate"
YourAppDelegateFileNameHere *theAppDelegate = (YourAppDelegateFileNameHere *)[[UIApplication sharedApplication] delegate];
// now you can use the dot notation if you wanna access a variable
int SomeNewInteger = theAppDelegate.someIntegerYouHaveStored;
// or some array you have stored
return [theAppDelegate.someArrayYouCreated count];
}
Hope that helps!
Ran into something interesting, want to know if I'm doing something wrong or if this is the correct behavior.
I have a custom UITableViewController. I ASSUMED (first mistake) that if you initialize as such:
[[CustomTableController alloc] init];
it would automatically load from a XIB of the same name, CustomTableController.xib, if it is in the same directory and such.
HOWEVER
This does not work; doesn't load the XIB. BUT, if I change the parent class of my controller from 'UITableViewController' to 'UIViewController', EVERYHTING WORKS FINE!
Calling:
[[CustomTableController alloc] init];
loads the controller and view from my xib.
Am I doing something wrong? Is this a bug? Expected behavior?
Most of the classes in Cocoa Touch list a "designated initializer" that you're supposed to call from your init methods when you subclass them. When you create your own custom class, it's a good idea to check the documentation to find the designated initializer for your superclass. When you initialize the class using some other initializer from a more general superclass (which you're doing by calling - [NSObject init] in this case), you rob your direct superclass of its opportunity to properly initialize its state. Sometimes you can get away with this. Often you can't.
UIViewController's documentation states that its designated initializer is -initWithNibName:bundle:. If you call this method with a nil nibName, it will look for a nib that matches your class name. The behavior of -init is undocumented for UIViewController. Based on the behavior you're seeing, it seems like it may be calling [self initWithNibName:nil bundle:nil], but it would be safer to call initWithNibName:bundle: directly rather than relying on this undocumented behavior.
UITableViewController only defines a single initializer, -initWithStyle: (although it doesn't specify this method as the designated initializer). This method initializes your UITableViewController without using a nib, which is usually fine. Since you don't add subviews to a UITableView, there usually isn't much to be gained by configuring your UITableViewController via a nib.
If decide you want to configure your UITableViewController via a nib anyway, the documentation tells us that we can safely bypass -initWithStyle: and call UIViewController's initWithNibName:bundle: method. Here is what the documentation tells us about how our UITableView and its controller will be initialized in each case:
If a nib file is specified via the initWithNibName:bundle: method (which is declared by the superclass UIViewController), UITableViewController loads the table view archived in the nib file. Otherwise, it creates an unconfigured UITableView object with the correct dimensions and autoresize mask. You can access this view through the tableView property.
If a nib file containing the table view is loaded, the data source and delegate become those objects defined in the nib file (if any). If no nib file is specified or if the nib file defines no data source or delegate, UITableViewController sets the data source and the delegate of the table view to self.
In summary, the documentation for most Cocoa Touch classes either specify a single designated initializer or a handful of initializers that you can call safely from your subclasses. Always refer to the documentation for your superclass to figure out which initializer your subclass should call.
whats os the difference between initWithNibName and ViewDidLoad methods ?
can i use them both?
initWithNibName - is what you call to create a view controller from specified nib file.
viewDidLoad - is what system calls on your controller after the controller’s view is loaded into memory. You can implement this method to perform some additional initialization (which is not done in nib file)
I think you may be confusing things here. nibNameOrNil is (usually) an argument name, frequently for -initWithNibName:bundle:. As such, it should be the name of your nib (.xib) file. -viewDidLoad is a method, and is called after your viewController has had it's view instantiated for the first time.