objective C:从UIButton类的子类创建的按钮不起作用

Zhe*_*hen 14 objective-c uibutton ios

我正在创建一个UIButton的子类,以创建我自己的自定义按钮.我的代码如下:

//interface file (subclass of uIButton
@interface UICustomButton : UIButton 
{
    Answer *answer;
    NSString *btnType;
}

@property (nonatomic, retain) Answer *answer;
@property (nonatomic, assign) NSString *btnType;

- (id)initWithAnswer:(Answer *)ans andButtonType:(NSString *)type andFrame:(CGRect)frame; 
- (void)buttonPressed;

@end


//Implementation file (.m)
@implementation UICustomButton
@synthesize answer,btnType;

- (id)initWithAnswer:(Answer *)ans andButtonType:(NSString *)type andFrame:(CGRect)frame; 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        self = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        self.backgroundColor = [UIColor colorWithHexString:@"#E2E4E7"];

    }

    [self addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlStateNormal];

    self.answer = ans;
    self.btnType = type;

    return self;
}
Run Code Online (Sandbox Code Playgroud)

我在使上述代码工作时面临一些问题.我有2个问题

1)按钮没有响应选择器方法"buttonPressed"

2)我遇到了行'self.answer = ans'和'self.btnType = type'堆栈跟踪的运行时错误,如下所示:

-[UIButton setAnswer:]: unrecognized selector sent to instance 0x614ebc0
2011-06-23 00:55:27.038 onethingaday[97355:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButton setAnswer:]: unrecognized selector sent to instance 0x614ebc0'
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

Fel*_*ino 30

这是因为您正在创建一个UIButton类型对象而不是UICustomButtoninit方法中的类型

self = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
Run Code Online (Sandbox Code Playgroud)

尝试替换您的init方法

- (id)initWithAnswer:(Answer *)ans andButtonType:(NSString *)type andFrame:(CGRect)frame; 
{
    self = [self initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    if (self) 
    {
        self.backgroundColor = [UIColor colorWithHexString:@"#E2E4E7"];

        [self addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];

        self.answer = ans;
        self.btnType = type;
    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

这将导致self成为一个UICustomButton类型对象.

此外,使用该addTarget:action:forControlEvents:方法将目标添加到按钮时,您使用了错误的UIControlState参数类型

你应该使用下面的值:

UIControlEventTouchDown
UIControlEventTouchDownRepeat
UIControlEventTouchDragInside
UIControlEventTouchDragOutside
UIControlEventTouchDragEnter
UIControlEventTouchDragExit
UIControlEventTouchUpInside
UIControlEventTouchUpOutside
UIControlEventTouchCancel


编辑: 关于UIButton子类化的注释

网上的许多参考文献都说你不应该把这个UIButton类子类化,但是不仅有人说过为什么,而且让我深感不安的是UIButton Class Reference根本就没有提到它.

例如,如果您使用UIWebView类参考,它会明确声明您不应该进行子类化UIWebView

子类注释UIWebView类不应该是子类.

最重要的UIButton是它继承自UIControl类参考本身的UIControl一个好的和简单的解释

子类注释您可能希望扩展UIControl子类有以下两个原因:

  • 观察或修改向特定事件的目标发送动作消息
  • 提供自定义跟踪行为(例如,更改突出显示外观)

因此,这意味着你的CAN子类UIButton,但你要小心你在做什么.只是将其子类化以改变其行为不是外观.要修改UIButton外观,您应该使用为其提供的接口方法,例如:

setTitle:forState:
setBackgroundImage:forState:
setImage:forState:

参考资料值得一读

来源:我在这里的帖子

  • 如果我遵循这种思维方式,我将无法创建一个`UIView`,因为doc也没有显示`init`方法.你刚忘了继承部分.`UIButton`文档不需要显示`init`方法,因为它继承自`NSObject`.以"UIImageView"为例,doc有一个`initWithImage`方法,但是没有`init`,即使没有什么能阻止我用`init`创建它,然后设置`image`属性. (8认同)
  • -1.如果这样可行,那就充其量只是一种破解.只有一种正确的方法来制作一个按钮,即使用工厂方法`+ buttonWithType:`. (2认同)

Jon*_*nny 10

不确定这是在以前的文档中,但无论如何这些是当前关于+ (id)buttonWithType:(UIButtonType)buttonType...的说明

对我来说,只要您使用init而不是使用子类化就可以了buttonWithType.不过我自己还没试过.

讨论此方法是一种便捷构造函数,用于创建具有特定配置的按钮对象.它是UIButton的子类,此方法不返回子类的实例.如果要创建特定子类的实例,则必须直接分配/初始化按钮.

创建自定义按钮(即具有UIButtonTypeCustom类型的按钮)时,按钮的框架最初设置为(0,0,0,0).在将按钮添加到界面之前,应将帧更新为更合适的值.