我正在CustomLabel class
中子类化UILabel
。当我尝试使用简单的UILabel
时,我遇到了问题,我想在将来对其他元素进行子类化。我已经读到我可以创建一个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
我在我的视图控制器中称之为自定义标签。
@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];
如何对UI元素进行子类化,如UILabel,UIButton
没办法。
我已经读到我可以创建一个类别
UILabel
没错。事实上,如果你想扩展类,你可能应该使用一个类别来代替(见前面的答案)。
它在 setFont 方法中失败。
您没有说明它是如何"失败"的,但我只能猜测它会导致无限递归和堆栈溢出/分段错误。那是因为
self.font = font;
等效于
[self setFont:font];
因此,您无条件地从自身内部调用该方法。
如果您不需要自定义这些属性的行为,只需不要管它们。 :)如果你这样做了,那么当你完成后,只需调用超类的实现:
- (void)setFont:(UIFont *)font
{
[self doScaryCustomMagicStuff];
[super setFont:font];
}
这实际上取决于您要实现的目标,类别不能具有属性,因此在您的示例中它们将不起作用。
你在这里的问题是,在二传手中,你正在召回二传手:
-(void)setFont:(UIFont *)font
{
self.font = font;
}
编译为(与以下相同):
-(void)setFont:(UIFont *)font
{
[self setFont:font];
}
您应该能够看到此问题。一旦调用此方法,就无法摆脱此方法。您在这里混淆了属性和实例变量。重写资源库不应通过属性设置,而应直接设置到实例变量。所以:
// LOOK AT EDIT -- Do not do this for 'font'
-(void)setFont:(UIFont *)font
{
_font = font;
}
编辑:
我没想清楚。由于您正在子类化UILabel
因此您已经有一个font
属性。你不应该直接指定它,因为你的超类(UILabel
)已经有了它。因此,请摆脱该属性声明。话虽如此,如果不需要color
,类别可能是更好的解决方案。无论如何,您可以像这样覆盖setFont:
方法:
-(void)setFont:(UIFont *)font
{
[super setFont:font];
// do custom stuff
}
由于color
不是UILabel
属性,您应该通过实例变量(如上所示:_color = color
)设置它,不要在此setter上调用super,因为UILabel
不会响应它。
super
调用是调用UILabel
的实现,因为你是它的子类。
如果要扩展项目的功能,则应使用类别;例如向 UILabel 添加一个函数,应用程序中的任何 UILabel 都可以执行该函数。
但是,如果你想在应用的多个位置使用类似的 UILabel,那么你应该对 UILabel 进行子类化,在 initWithFrame 或 awakeFromNib 中相应地修改它,并在任何你想要的地方使用你的自定义实现。
在您的情况下,我建议将其子类化。标准UILabel中已经存在SetFont方法,您可以使用setTextColor而不是setColor。
UIButton,但根据苹果的说法,UILabel可以通过子类自由定制。来自苹果文档:
基 UILabel 类为标签文本的简单样式和复杂样式提供支持。您还可以控制外观的各个方面,例如标签是使用阴影还是使用高光进行绘制。如果需要,您可以通过子类化进一步自定义文本的外观。