What awakeFromNib really is? - objective-c

I'm just a newbie of Objective C iPhone programming... I see a lot of codes that contains method named "awakeFromNib".. What does it really mean? how and when and where to call this method?
Thanks...

awakeFromNib is called for objects (views, controllers, etc.) that are being archived in xib/nib files. This basically means that xib/nib was unarchived, all connections (IBActions/IBOutlets) for all objects are made and you have a working object graph.
I use it when I have a custom view class that I gave to a certain view in my xib.

You don't call it. After nib file load, every view inside of it, be it button, UIView or something else, calls awakeFromNib from their respective class automatically. You override this method for setup and layout, as you would do with init method if you were creating a subview programmatically.

Related

What's the advantage of using UIViewController as owner of xib?

Most of the time, owners of xib is a UIViewController.
I sort of use it my self.
Still I am confused why.
I suppose, the viewDidLoad and viewWillAppear is kind of the main selling point.
Is that it?
What are the advantage of using UIViewController as owners of an XIB?
A UIViewController object is the main way for views to appear within an iOS window.
Apple provides this as a fundamental, foundational building block (along with so many others) which you can use to build upon quickly and get your app out to market.
And when you subclass UIViewController, you're able to do lots of beautiful customizations which can be collected and eventually turned into (hopefully decent) products. When you subclass a UIViewController, you need to set the "owner" of a XIB file to that subclassed view controller (e.g. ThioViewController), so that way the app knows what object (and user interface) is being instantiated.
Hopefully this isn't too super abstract of an explanation.
First, spend a bit time to understand MVC http://en.wikipedia.org/wiki/Model–view–controller
This is the milestone of Objective-C (not only) development.
UIViewController is controller for all your views (inside this viewController). It provide starting point for you to create views on the screen, manipulate the views, handle actions from views etc.
You can create UIViewController programmatically.
XIB is representation of the screen which you can comfortably operate in Interface Builder to create and customize design of your application screen or one of the screens.
Since XIB represent the screen(view) it must be the controller which controls all the view on the screen - UIViewController or UINavigationController or other type of controller depending of your needs.
Most of time you will subclass UIViewController and use it to achieve you goals.
UIViewController have several subclasses which inherit directly from it (UINavigationController, UITabBarController).
Also UIViewController hav several methods (some of them)
-(void)viewDidLoad
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.
and
-(void)viewWillAppear:(BOOL)animated
Parameters
animated
If YES, the view is being added to the window using an animation.
Discussion
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Please check Apple documentation for more information
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

Loading nib using loadNibNamed:owner:options: designate initializer

I have a nib file with its class (UIView) assigned to it in the inspector, So when I need to show that view I loaded it using the method :
loadNibNamed:owner:options:
So if I have to do some initialization when I load the nib, what is the way to know that in the nib's UIView class like the initWithNibName:bundle For the UIViewController?
I appreciate any help :)
You want to use a combination of initWithCoder: and awakeFromNib which are each called at different times during the instantiation (the former) and configuration (the latter).

Subclassing in IB

I have UIScrollView added to the main window of the app with IB.
What I want is that view to subclass UICustomScrollView instead of UIScrollView. To do that I choose the UIScrollView and then I change Custom class to UICustomScrollView in identity inspector. I have put some NSLog messages in init method of UICustomScrollView. When I run the app UICustomScrollView seem like it is not used because NSLog messages in init are not printed.
What I miss here ?
Here's what the UIView Class Reference has to say about initWithFrame::
If you use Interface Builder to design your interface, this method is not called when your view objects are subsequently loaded from the nib file. Objects in a nib file are reconstituted and then initialized using their initWithCoder: method, which modifies the attributes of the view to match the attributes stored in the nib file.
If your NSLog is only in initWithFrame, it won't be called if the view is loaded from a nib.

The relationship between UIViewController and UIView

I'm trying to understand how these two are connected. Every time you make a UIViewController does it also automatically come with its own UIView?
Also are these from Cocoa or Objective-C?
UIViewController is a Cocoa Touch class built for the purpose of managing UIViews. It expects to have a view hierarchy, but you don't "automatically" get a view (this is slightly inaccurate; see edit below). Usually you will obtain views by calling initWithNibName on your view controller.
There is some built-in magic in Interface Builder which knows that if File's Owner is a UIViewController (or subclass), there is a property called view. That's about it.
Once you have linked a view controller and a view, the view controller does a fair amount of work for you: it registers as a responder for view touch events, registers for device rotation notifications (and handles them automatically, if you wish), helps you take care of some of the details of animation, and handles low-memory conditions semi-automatically.
Edit: correction—if you don't call initWithNibName or set the view property manually, the view property getter will invoke loadView if view is nil. The default implementation of loadView will see if you've set nibBundle and nibName and attempt to load the view from there (which is why you don't have to call initWithNibName, most of the time), but if those properties aren't set, it will instantiate a UIView object with default values. So technically, yes, it does automatically come with its own UIView, but most of the time that's of little value.
UIViewController doesn't automatically come with a view. You have to make a view in the -loadView method. By default, this loads the view from the nib file you've specified. You can also override this method to make a custom view if you prefer not to use a nib.
Also, the view is not created right when the UIViewController is created. UIViewController uses a technique known as lazy-loading to defer the creation of a view until the view is actually accessed for the first time.

Making sure that objects in nibs are initialized before applicationDidFinishLaunching

and thanks for taking a look at my problem.
i have two view controllers in my app and each has its own nib file. an instance of controller1 is stored in MainWindow.xib and an instance of controller 2 is in Controller1.xib.
is there a way to make sure that controller 2 is initialized before the app delegate is sent applicationDiDFinishLaunching?
the actual setup is much more complicated with many other view controllers, so i really don't want to put everything into MainWindow.xib. plus doing so will reduce reusability.
thanks again!
is there a way to make sure that controller 2 is initialized before the app delegate is sent applicationDiDFinishLaunching?
No. Well, maybe yes, but it's not how view controllers are supposed to work. The view controller is there to defer the loading of the nib, which is a rather expensive operation, until the view is really, really necessary. So, if you need controller2 right when applicationDidFinishLaunching is called, you shouldn't put it inside the nib which is controlled by another view controller.
If I were you, I would stop instantiating the view controllers in the nib file at all, and just create them inside applicationDidFinishLaunching:, as in
-(void)applicationDidFinishLaunching:(UIApplication *)application
{
....
self.controller2=[[Controller2 alloc] init... ];
....
}
I believe applicationDidFinishLaunching is the absolute entry point in which you have control of the code. That's conceivably the earliest place to load anything.