【问题标题】:iOS Programming: Problem extending UIButton classiOS 编程:扩展 UIButton 类的问题
【发布时间】:2011-05-21 13:40:05
【问题描述】:

我正在尝试扩展 UIButton 类以添加一些方法,但是当我尝试初始化我的对象时遇到了一些问题。

-(id)init{

UIImage* image = [UIImage imageNamed:@"button_background.png"];    
CGRect frame=  CGRectMake(100.0, 70.0, 45.0 ,45.0);

self.frame = frame;

[self setTitle:@"title" forState:UIControlStateNormal];
[self setBackgroundImage:image forState:UIControlStateNormal];
[self setImage:image forState:UIControlStateNormal];

NSLog(@"type: %d",self.buttonType);
NSLog(@"x: %f\ny: %f\nwidth: %f\nheight: %f",frame.origin.x, frame.origin.y ,frame.size.width, frame.size.height);
NSLog(@"x: %f\ny: %f\nwidth: %f\nheight: %f",self.frame.origin.x, self.frame.origin.y ,self.frame.size.width, self.frame.size.height);

if(self != nil){
    //
}
return self;

}

它可以正常工作,执行过程中没有警告或错误。 但是在控制台中会出现frame和self.frame的值有些不一致,当然按钮也不会出现在屏幕上。

type: 0
x: 100.000000
y: 70.000000
width: 45.000000
height: 45.000000

x: 0.000000
y: 0.000000
width: 0.000000
height: -1.998576

请帮帮我,我快疯了! :\

【问题讨论】:

  • 记住 UIButton 是一个类簇。请参阅与子类化 UIButton 相关的这些 SO 问题:123
  • 另外,继承UIControl 而不是UIButton 是最安全的。第一个用于子类化,第二个......

标签: ios cocoa-touch uibutton


【解决方案1】:

当您在 Objective-C 中进行子类化时,您必须 (1) 覆盖指定的初始化程序 (2) 调用超类的指定初始化程序。你也不做。

你应该这样做:

/** 
 * \brief Convenience class method to replace button method of UIButton
 */
+(id)myButton
{
    MyButton* myButton = [[MyButton alloc] 
                              initWithFrame:CGMakeRect(100.0, 70.0, 45.0, 45.0)];
    return [myButton autorelaase];
}

-(id)initWithFrame:(CGRect)f
{
    if(self = [super initWithFrame:f])
    {
        UIImage* image = [UIImage imageNamed:@"button_background.png"];    

        [self setTitle:@"title" forState:UIControlStateNormal];
        [self setBackgroundImage:image forState:UIControlStateNormal];
        [self setImage:image forState:UIControlStateNormal];

        NSLog(@"type: %d",self.buttonType);
        NSLog(@"x: %f\ny: %f\nwidth: %f\nheight: %f", NSStringFromCGRect(frame));
        NSLog(@"x: %f\ny: %f\nwidth: %f\nheight: %f", NSStringFromCGRect(self.frame));
    }
    return self;
}

希望这会有所帮助。如果您需要更多信息,请告诉我。

【讨论】:

    【解决方案2】:

    在您登录的那一刻,您没有将按钮添加到任何视图中。 无论如何,代码必须看起来像这样?

    -(id)init{
    
    
    
    if(self != nil){
        UIImage* image = [UIImage imageNamed:@"button_background.png"];    
    CGRect frame=  CGRectMake(100.0, 70.0, 45.0 ,45.0);
    
    self.frame = frame;
    
    [self setTitle:@"title" forState:UIControlStateNormal];
    [self setBackgroundImage:image forState:UIControlStateNormal];
    [self setImage:image forState:UIControlStateNormal];
    
    NSLog(@"type: %d",self.buttonType);
    NSLog(@"x: %f\ny: %f\nwidth: %f\nheight: %f",frame.origin.x, frame.origin.y ,frame.size.width, frame.size.height);
    NSLog(@"x: %f\ny: %f\nwidth: %f\nheight: %f",self.frame.origin.x, self.frame.origin.y ,self.frame.size.width, self.frame.size.height);
    }
    return self;
    

    顺便说一句,你不会忘记调用超类 init 吗?

    【讨论】:

    • 我在另一段代码中将按钮添加到当前视图。将代码放在“if(self!= nil)”中只是为了编写更安全的代码。然而真正的问题是我没有调用 [super initWithFrame:frame] 现在它可以工作了!谢谢!
    【解决方案3】:

    我刚刚在这里回答了一个非常相似的问题: How to create a very custom uibutton like UITableViewCellStyleSubtitle in iOS

    就像其他人指出的那样,UIButton 是一个类集群,因此您可能不想对其进行子类化。但是,您可能会发现创建 UIButton 类别更容易,而不是继承 UIControl。

    【讨论】:

      猜你喜欢
      • 2017-02-07
      • 2023-04-06
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 2015-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多