Subclasses of UIButton loaded from nibs are not initialized properly

时光毁灭记忆、已成空白 提交于 2019-12-14 03:47:19

问题


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 identity to MyButton.

When running, 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 not a round rect button anymore.

Observed on both iOS 3.2 and iOS 4.

Is this a bug or am I missing something obvious?

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


回答1:


Programmatically, you instantiate a button with +[UIButton buttonWithType:] which is actually a factory that returns a subclass of UIButton. So if you derive from UIButton you actually don't derive from your round rect button class (UIRoundedRectButton) but from a generic button class. But you are not allowed to subclass from UIRoundedRectButton AFAIK since it's an internal class.

It seems to be problematic to derive from UIButton, I've seen a lot of people recommed to derive from UIControl instead and implement the drawing yourself.

But you might find these articles helpful:

How to override -drawrect in UIButton subclass?

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 derive from UIButton, but if you want to do some customization that does not involve overwriting any other methods it might be helpful 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;
}



回答2:


I’m not sure if this is acceptable for your needs, but I tend to prefer to override -awakeFromNib instead of -initWithCoder: in these circumstances. Does doing this resolve the issue you’re seeing?



来源:https://stackoverflow.com/questions/3638053/subclasses-of-uibutton-loaded-from-nibs-are-not-initialized-properly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!