如何子类UILabel,UIButton等UI元素
我在CustomLabel class
中CustomLabel 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自定义文本的外观。