I made a subclass of UIView
that has a fixed frame. So, can I just override init
instead of initWithFrame:
? E.g.:
- (id)init {
if ((self = [super initWithFrame:[[UIScreen mainScreen] bounds]])) {
self.backgroundColor = [UIColor clearColor];
}
return self;
}
The Xcode documentation for -initWithFrame:
says: "If you create a view object programmatically, this method is the designated initializer for the UIView
class. Subclasses can override this method to perform any custom initialization but must call super
at the beginning of their implementation."
What does "designated initializer" mean?
The designated initializer is the one that all the other initializers must call. UIView
and subclasses are a little unusual in that they've actually got two such initializers: -initWithFrame:
and -initWithCoder:
, depending on how the view is created. You should override -initWithFrame:
if you're instantiating the view in code, and -initWithCoder:
if you're loading it from a nib. Or, you could put your code in third method and override both those initializers such that they call your third method. In fact, that's often the recommended strategy.
So, for example, you might create a UIView subclass, ClueCharacter
, that has its own initialization method: -initWithPerson:place:thing:
. You then create your view like this:
Obj-C:
ClueCharacter *mustard = [[ClueCharacter alloc] initWithPerson:@"Col. Mustard"
place:kInTheStudy
thing:kTheRope];
Swift:
var mustard = ClueCharacter("Col. Mustard", place: kInTheStudy, thing: kTheRope)
That's fine, but in order to initialize the UIView part of the object, your method must call the designated initializer:
Obj-C:
-(id)initWithPerson:(NSString*)name place:(CluePlace)place thing:(ClueWeapon)thing
{
if ((self = [super initWithFrame:CGRectMake(0, 0, 150, 200)])) {
// your init stuff here
}
}
Swift:
func init(name: String, place : CluePlace, thing : ClueWeapon)
{
if (self = super.init(CGRectMake(0, 0, 150, 200))) {
// your init stuff here
}
}
If you want to call your subclass's initializer -init
, that's okay as long as you call -initWithFrame:
in the implementation.