如何子类UILabel,UIButton等UI元素

我在CustomLabel classCustomLabel class UILabel 。 当我尝试使用一个简单的UILabel时,我遇到了一些问题,并且我希望将来能够inheritance其他元素。 我读过,我可以创build一个UILabel category 。 哪个更好? 类别或子类?

这是我的代码试图子类。 它在setFont方法中失败。

 @interface WPCustomLabel : UILabel @property (strong, nonatomic) UIColor *color; @property (strong, nonatomic) UIFont *font; @end #import "WPCustomLabel.h" @implementation WPCustomLabel - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setBackgroundColor:[UIColor clearColor]]; } return self; } -(void)setColor:(UIColor *)color { self.color = color; } -(void)setFont:(UIFont *)font { self.font = font; } @end 

我在我的ViewController中调用这个CustomLabel。

 @property (strong, nonatomic) WPCustomLabel *titleLbl; titleLbl = [[WPCustomLabel alloc] initWithFrame:CGRectMake(75, 25, 200, 14)]; [titleLbl setTextColor:[UIColor blackColor]]; [titleLbl setFont:[UIFont systemFontOfSize:14]]; [titleLbl setBackgroundColor:[UIColor clearColor]]; [titleLbl setText:@"Here I AM"]; [self.view addSubview:titleLbl]; 

如何子类UILabel,UIButton等UI元素

绝不。

我读过,我可以创build一个UILabel类别

那就对了。 事实上,如果你想扩展这个类,你应该使用一个类别来代替(见前面的答案)。

它在setFont方法中失败。

你没有说明它是如何“失败”的,但我所能猜到的是它会导致无限recursion和堆栈溢出/分段错误。 那是因为

 self.font = font; 

相当于

 [self setFont:font]; 

所以你无条件地从内部调用这个方法。

如果你不需要自定义这些属性的行为,只是留下他们一个人。 🙂 如果你这样做,那么只要在完成时调用超类的实现:

 - (void)setFont:(UIFont *)font { [self doScaryCustomMagicStuff]; [super setFont:font]; } 

这实际上取决于你想要达到的目标,虽然在你的例子中,类别不能有属性,但是它们是行不通的。

你在这里的问题是,在debugging者中,你正在调用setter:

 -(void)setFont:(UIFont *)font { self.font = font; } 

编译成(与之相同):

 -(void)setFont:(UIFont *)font { [self setFont:font]; } 

你应该可以看到这个问题。 一旦你打电话,没有办法摆脱这种方法。 你在这里混淆了属性和实例variables。 重写setter不应该通过属性设置,而是直接设置为实例variables。 所以:

 // LOOK AT EDIT -- Do not do this for 'font' -(void)setFont:(UIFont *)font { _font = font; } 

编辑:

我并没有直视。 由于你是UILabel的子类,你已经有一个font属性。 你不应该直接指定这个,因为你的超类( UILabel )已经有了。 所以摆脱那个属性声明。 这就是说,如果不需要color ,一个类别可能会是一个更好的解决scheme。 无论如何,你可以覆盖你的setFont:方法是这样的:

 -(void)setFont:(UIFont *)font { [super setFont:font]; // do custom stuff } 

由于color不是一个UILabel属性,你应该通过实例variables(如上面的: _color = color )来设置它,不要在这个setter上调用super,因为UILabel不响应它。

super调用正在调用UILabel的实现,因为你是它的一个子类。

如果要扩展项目的function,则应该使用这些类别; 比如向应用程序中的任何UILabel可以执行的UILabel添加一个函数。

但是,如果你想在你的应用程序的几个地方使用类似的UILabel,那么你应该inheritanceUILabel的子类,在initWithFrame或者awakeFromNib里相应地修改它,然后在你想要的地方使用自定义的实现。

在你的情况下,我build议子类化它。 标准UILabel中已经存在SetFont方法,您可以使用setTextColor代替setColor。

我不知道UIButton,但根据苹果UILabel可以自由定制的子类。 从Apple文档:

基本的UILabel类为标签文本的简单和复杂样式提供支持。 您还可以控制外观的各个方面,例如标签是使用阴影还是使用高光进行绘制。 如果需要,可以通过inheritance自定义文本的外观。