【问题标题】:Subclasses of UIButton loaded from nibs are not initialized properly从 nib 加载的 UIButton 的子类未正确初始化
【发布时间】:2010-09-03 17:20:07
【问题描述】:

我有一个非常简单的 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

在 Interface Builder 中,我添加了一个 UIButton,将其按钮类型设置为 Rounded Rect,并将其类标识设置为 MyButton

运行时,我有以下日志:

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

但按钮不再是圆形矩形按钮了。

在 iOS 3.2 和 iOS 4 上均观察到。

这是一个错误还是我遗漏了一些明显的东西?

以编程方式创建 MyButton 的实例不是可接受的答案,谢谢。

【问题讨论】:

    标签: iphone nib


    【解决方案1】:

    以编程方式,您使用+[UIButton buttonWithType:] 实例化一个按钮,它实际上是一个返回UIButton 子类的工厂。因此,如果您从 UIButton 派生,您实际上不是从圆形矩形按钮类 (UIRoundedRectButton) 派生,而是从通用按钮类派生。但是你不能继承UIRoundedRectButtonAFAIK,因为它是一个内部类。

    从 UIButton 派生似乎有问题,我看到很多人建议从 UIControl 派生而不是自己实现绘图。

    但您可能会发现这些文章很有帮助:

    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/

    另外,我不知道您为什么要从 UIButton 派生,但如果您想做一些不涉及覆盖任何其他方法的自定义,那么使用您可以执行以下操作的事实可能会有所帮助:

    - (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;
    }
    

    【讨论】:

    • 上面的代码看起来很有希望,但我不能让它工作。我以为我可以用它来对 IBOutlet UIButton 执行自定义,但是唉。我很想知道支持这个答案的两个人是如何实现它的。
    • 我无法推断我们应该做什么来解码帧。有什么提示吗?
    • @jemmons:你可以使用NSStringFromCGRectCGRectFromString
    • @DarkDust 谢谢!虽然这不是神秘的部分。我从哪里得到我 CGRectFromString 我的 rect 的字符串? decoder 没有“框架”、“矩形”、“边界”甚至“大小”或“中心”的任何键。那么你到底做了什么来解码帧?
    • 要么自己编码和解码,要么尝试调用[super initWithCoder:][super encodeWithCoder:]。如果您仍有问题,请提出新问题,而不是在 cmets 中讨论。
    【解决方案2】:

    我不确定这是否能满足您的需求,但在这些情况下,我倾向于覆盖 -awakeFromNib 而不是 -initWithCoder:。这样做能解决您遇到的问题吗?

    【讨论】:

    • +1 我不明白你为什么在这里被否决,这是一个有效的答案。
    猜你喜欢
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 2013-08-04
    • 2022-01-25
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多