UIButton subclasses loaded from knives are not initialized properly

I have a very simple subclass of UIButton:

@interface MyButton : UIButton @end @implementation MyButton - (id) initWithCoder:(NSCoder *)decoder { if (!(self = [super initWithCoder:decoder])) return nil; NSLog(@"-[%@ initWithCoder:%@]", self, decoder); return self; } @end 

In Interface Builder, I add a UIButton, set its button type to Rounded Rect and its class identifier MyButton .

At startup, I have the following log:

 -[<MyButton: 0x5b23970; baseClass = UIButton; frame = (103 242; 114 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x5b23a90>> initWithCoder:<UINibDecoder: 0x6819200>] 

but the button is no longer a round button.

It is observed both on iOS 3.2 and iOS 4.

Is this a mistake or am I missing something obvious?

Creating an instance of MyButton programmatically is not an acceptable answer, thanks.

+4
source share
2 answers

Programmatically, you create a button with +[UIButton buttonWithType:] , which is actually a factory that returns a subclass of UIButton. Therefore, if you exit UIButton, you do not actually get your round rectangular class ( UIRoundedRectButton ), but from the general class of buttons. But you are not allowed to subclass from UIRoundedRectButton AFAIK, as this is an inner class.

It seems that the problem is related to UIButton, I saw how many people recommended extracting from UIControl and implementing the drawing themselves.

But you may find these articles useful:

How to override -drawrect in a subclass of UIButton?

http://www.cocoabuilder.com/archive/cocoa/284622-how-to-subclass-uibutton.html

http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/

Also, I don't know why you want to get UIButton, but if you want to make some tweaks that don't include overwriting other methods, it may be useful to use the fact that you can do something like this:

 - (id)initWithCoder:(NSCoder *)decoder { // Decode the frame CGRect decodedFrame = ...; [self release]; self = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self setFrame:decodedFrame]; // Do the custom setup to the button return self; } 
+4
source

I'm not sure if this is acceptable for your needs, but I prefer to override -awakeFromNib instead of -initWithCoder: in these circumstances. Does this solve the problem you see?

+1
source

All Articles