Our current best-practice for custom views is:
- Build the custom view in a Nib.
- In the view controller, programmatically load the Nib, get the custom view from the array of loaded objects (we do this in a UIView category method
+loadInstanceFromNib
). - Add custom view as subview, set its frame.
What we actually want is to "embed" the custom-view Nib inside the view-controller Nib. Failing that, at least we'd like to add and position a custom-view instance inside the view-controller Nib (without seeing its contents).
We have come very close with the following solution:
@implementation CustomView
static BOOL loadNormally;
- (id) initWithCoder:(NSCoder*)aDecoder {
id returnValue = nil;
if (loadNormally) { // Step 2
returnValue = [super initWithCoder:aDecoder];
loadNormally = !loadNormally;
} else { // Step 1
loadNormally = !loadNormally;
returnValue = [CustomView loadInstanceFromNib];
}
return returnValue;
}
- (id) initWithFrame:(CGRect)frame {
loadNormally = YES;
self = (id) [[CustomView loadInstanceFromNib] retain];
self.frame = frame;
return self;
}
// ...
@end
If we instantiate the custom view programmatically, we use -initWithFrame:
, which will load the view from the Nib (which will call -initWithCoder:
and go right to the if-branch labeled "Step 2"), set its frame, and set its retain count to 1.
However if we instantiate the custom view inside a view-controller Nib, the (admittedly rather ugly) static loadNormally
variable is initially NO
: We start in "Step 1", where we load and return the instance loaded from its Nib, after making sure that we will forthwith use the "normal" if-branch of -initWithCoder:
. Loading from the custom-view Nib means that we come back into -initWithCoder:
, this time with loadNormally==YES
, i.e. we let the Nib loading mechanism do its job and return the custom-view instance.
Results, in summary:
- The good: IT WORKS!!! We have "pluggable" custom views in Interface Builder!
- The bad: An ugly static variable… :-/
- The ugly: An instance of the custom view is leaked! This is where I'd love your help – I don't understand why. Any ideas?