I am working on an application where the bulk of the UI is setup via a Storyboard in Xcode. One thing that I want to do is specify "Finished" images for the UITabBarItems on a TabBar rather than the default "Stencilled" images that you can access via Interface Builder.
My question is where is the best place to do this, I am currently doing it in awakeFromNib as it needs to be done when things are unarchived from the storyboard, but I as unsure if I should be using initWithCoder: instead, which is best does it matter?
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if(self) {
UIImage *tabIn = [UIImage imageNamed:@"TAB_IN"];
UIImage *tabOut = [UIImage imageNamed:@"TAB_OUT"];
UITabBarItem *tabBarItem = [self tabBarItem];
[tabBarItem setFinishedSelectedImage:tabOut withFinishedUnselectedImage:tabIn];
[tabBarItem setTitle:@"TWO"];
}
return self;
}
OR
- (void)awakeFromNib {
[super awakeFromNib];
UIImage *tabIn = [UIImage imageNamed:@"TAB_IN"];
UIImage *tabOut = [UIImage imageNamed:@"TAB_OUT"];
UITabBarItem *tabBarItem = [self tabBarItem];
[tabBarItem setFinishedSelectedImage:tabOut withFinishedUnselectedImage:tabIn];
[tabBarItem setTitle:@"TWO"];
}
I understand that initWithCoder:
is called at the start of unarchiving objects from nibs (contained in the storyboard) when outlets and actions are not yet hooked up. I also understand that awakeFromNib
is called at the end of the unarchiving process and signals that the viewController is now ready for use. My feeling is that it really just depends on what you want to do, although using awakeFromNib
might prove less problematic as your not going to hit issues where outlets and actions are not yet hooked up.
Let me rephrase this, what situations would you use initWithCoder:
as apposed to awakeFromNib
and vice versa?
It seems that you've already answered your own question in the paragraph before edit.
The documentation states that
When an object receives an awakeFromNib message, it is guaranteed to have all its outlet instance variables set.
So if you have to access IBOutlet
ivars in your initialisation code, you have to do it in the awakeFromNib
method.
Although I prefer initWithCoder:
in cases when I do not need to access outlets because it is the proper initialiser method for objects being decoded with NSCoding
protocol according to NSCoding
documentation:
initWithCoder: instructs the object to initialize itself from data in the coder provided; as such, it replaces any other initialization method and is sent only once per object
As a side note though, it does not make much of a difference and in cases when I have to access outlets in my initialization code, I do not implement both awakeFromNib
and initWithCoder:
for the sake of simplicity. So if outlets are involved I usually implement awakeFromNib
and do all the initialisation there.