Sometimes traversing through the life-cycle callbacks of view loading on the
iPhone still gives me a headache. Especially when using Interface Builder (IB)
as part of the UI development, finding the right method to override in order to
get your custom drawing/init/etc. done can be more difficult than it may seem.
Recently, I was lost again in the quagmire of methods to choose from when building
UIView subclass that provided some basic look-and-feel customization
over the standard view structure. The answer that was revealed to me is today's tip.
The commonly recommended place to do custom initialization for custom views is
initWithCoder methods. When you are defining parts
of your UI in IB,
initWithCoder is the one of these that is called by the
nib-loading code. However, it is usually the case that any work done with members
declared as IBOutlet are still nil at this point, so your custom changes will
fall on deaf ears. This drives many developers to put custom initialization code
viewDidLoad method of the view controller...because it works.
The problem here is a conceptual one. You are no longer encapsulating all of the custom functionality for your view in the view class, some of the required custom code is leaking out into the controller. You are now relying on code in the custom view's container to provide some of the needed functionality to properly initialize the view, which makes the code brittle.
awakeFromNib — a UIKit addition to NSObject that receives a message from
the nib-loading code after all the outlets and actions have been connected for
all objects inside the nib file.
When an object receives an
awakeFromNibmessage, it is guaranteed to have all its outlet and action connections already established.
This means you can now comfortably make some changes to properties that would have otherwise been nil during the init phase. This allows you to put that custom code back into the view subclass, properly encapsulating the functionality.