In my RootViewController, I have IBOutlets. I can access them by viewWillAppear but they are all nil in awakeFromNib()
I am calling super.awakeFromNib()
Why are they all nil? Doesn't the Apple document guarantee that all the outlets from my view controller are initialized when awakeFromNib is called?
https://developer.apple.com/documentation/objectivec/nsobject/1402907-awakefromnib
Quote from the apple dev docs:
When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.
For a UIViewController method awakeFromNib is called when the controller is "awake" from Nib file. You should use viewDidLoad is you want to interact with outlets.
Related
CollectionViewCell is registered with the same name as used for identifier.
I checked the IBOutlets and they are connected to file and also, xib's file owner is also correct.
While you are accessing IBoutlets of cell in your cellForRow method, make sure you unrap the cell after calling dequeueReusableCellWithReuseIdentifier method.
I see that when view controller is loaded from storyboard, these events happen in order
awakeAfterUsingCoder
awakeFromNib
viewDidLoad
In awakeFromNib, I see that isViewLoaded == false. From
Which should I use, -awakeFromNib or -viewDidLoad?
awakeFromNib is called when the controller itself is unarchived from a nib. viewDidLoad is called when the view is created/unarchived. This distinction is especially important when the controller's view is stored in a separate nib file.
In the spec of awakeFromNib
The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive, but only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.
So which outlet and action does it mention? The other thing is that awakeAfterUsingCoder is called 3 times in my case !!!
This only works with nibs. As I understand if we're loading ViewControllers from storyboard awakeFromNib gets called but before the view and subviews are initialised. That's why there is no guarantee that the view and outlets will be initialised. So if you need the object with established outlet and action connections you need to start awakeFromNib with [self view] it`s like a little trick that helps.
So it seems like I should be setting my member variables in viewDidLoad - but I am confused as to why setting these variables in initWithCoder fails, since both are called at the start of the program.
In particular I have a line of code:
[worldView setMapType:MKMapTypeSatellite];
In which worldView is a IBOutlet MKMapView object. It works under viewDidLoad, but not initWithCoder.
The outlets are not yet connected when initWithCoder is called.
From the documentation:
During the instantiation process, each object in the archive is
unarchived and then initialized with the method befitting its type.
Objects that conform to the NSCoding protocol (including all
subclasses of UIView and UIViewController) are initialized using their
initWithCoder: method.
...
After all objects
have been instantiated and initialized, the nib-loading code
reestablishes the outlet and action connections for all of those
objects. It then calls the awakeFromNib method of the objects.
So awakeFromNib would be a suitable place for the custom setup of your UI elements.
The objects do not yet exist when initWithCoder is called, and they do when viewDidLoad is called. Check your initWithCoder method by logging out the value of worldView using something like:
NSLog(#"World View: %#", worldView);
and it will be nil. They will be initialized before the call to viewDidLoad, so you can set a property of that IBOutlet there.
I have a view controller that subclasses UITableViewController. When I push this VC onto the navigation stack, the UITableView delegate methods get called, then viewDidLoad gets called, then the delegate methods get called again. What is going on here?
Because your view is a subclass of UITableViewController, the delegate and datasource are attached from the very first moment it's created, and the methods are called as soon as the datasource is asigned.
Also, you can set a breakpoint on it and see which class called the datasource.
This question already has answers here:
What is the process of a UIViewController birth (which method follows which)?
(7 answers)
Closed 9 years ago.
I am a new developer, two questions as follows
In controller, why can't I call the awakeFromNib method?
-(void)awakeFromeNib
{
NSLog(#"awakeFromNib");// can't be printed ?
}
Do the methods awakeFromNib and initWithNibName , layoutSubviews have some relations?
When and where should I use them?
- (void)awakeFromNib is only called inside of an object that is being directly loaded from a nib or storyboard. This is usually not a UIViewController.
So, the reason awakeFromNib is not on a view controller is that the view controller is the one that is calling its subviews to awake from the nib as set from the method initWithNibName:bundle:. The layoutSubviews method is also called in a subclass of UIView since a view may have subviews that it needs to layout. If I'm not mistaken, the layoutSubviews on a UIView gets called after awakeFromNib.
Hope this helps!
awakeFromNib is called on the controller after all the connections in it's nib are created and set up.
initWithNibName is the designated initialiser for the class. You call this when you are creating the controller in code.
layoutSubviews is a method that you implement that allows you to give precise layout to subviews.
You should also know about initWithCoder which is the initialiser that is called when the controller is created from a xib file or a storyboard.
Your view controller was likely not awaken from a NIB and instead initialized initWithNibName:bundle:. Only objects that are initialized from a NIB get awakeFromNib.
There is a method that gets called when the view is initialized, either from a NIB or loadView: viewDidLoad
Using viewDidLoad accomplishes pretty much the same thing you'd be expecting from awakeFromNib.
You may be able to use awakeFromNib when your view controller is created from a storyboard, as Abizem suggests, but that will still invoke viewDidLoad immediately afterward.