I'm trying to decide on the best way to customize an initializer for UIView so a value can be passed into the initializer and it is immediately stored as an iVar in the UIView subclass, as this value is required for the drawing in drawRect
.
Currently I am using the default initWithFrame
and the class that creates this UIView then sets its iVar to a value after calling initWithFrame
, and it is in fact working; somehow the drawRect
is getting this iVar's value even though it is set after the UIView is initialized.
So I need either one of two things:
1) Confidence to know this is okay: that I can rely on drawRect
somehow delaying the drawing for a bit so iVars are set by another object after UIView is initialized. In which case, just when in the UIView initializing does drawRect
get called?
Or,
2) I need to pass value during initialization: is this the best way to create a custom initializer that takes more than (CGRect)frame
as an argument for initWithFrame.
Could it be as simple as doing this:
myNewView=[[MyCustomView alloc] initWithFrame:myRect andMore:myValue];
And then in MyCustomView.m:
- (id)initWithFrame:(CGRect)frame andMore:(int)someValue
{
self = [super initWithFrame:frame];
if (self) {
myIvar=someValue;
... //continue as normal
}
}
Would this code be a good approach? Then I would comfortably know that the value is there before drawRect
is called.
1.) You can rely on drawRect:
to be called after any init
. In fact, drawRect:
will be called when the view drawing and compositing is done, which usually happens as a result of a Core Animation commit (done at the end of the runloop if you modify any CALayer or UIView (which are always backed by a CALayer)).
2.) This approach is better from an architectural point of view. If you consider this variable to be an integral part to the functionality of your class (and the class can't work properly without it), it should definitely be an init parameter. you might also consider throwing an NSInternalInconsistencyException (or any other exception) inside other init-Methods and/or mark them as deprecated (init-Methods of the superclass will still work fine when called with super initWithFrame:
).
The second approach is ideal when you explicitly create the view programmatically using the designated initializer you have specified. Caveat: This will not be the case if the view is constructed via a NIB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With