[英]How to Subclass UI elements like UILabel, UIButton
我在CustomLabel class
中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
我在我的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];
如何子類化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];
}
你應該能夠看到這個問題。 一旦你打電話,就沒有辦法擺脫這種方法。 您在這里混淆屬性和實例變量。 覆蓋setter不應該通過屬性設置,而應該直接設置為實例變量。 所以:
// 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中相應地修改它,並在任何你想要的地方使用你的自定義實現。
在你的情況下,我建議繼承它。 SetFont方法已存在於標准UILabel中,您可以使用setTextColor而不是setColor。
我不知道UIButton,但根據Apple UILabel可以通過子類自由定制。 來自Apple文檔:
基礎UILabel類支持標簽文本的簡單和復雜樣式。 您還可以控制外觀的各個方面,例如標簽是使用陰影還是使用突出顯示。 如果需要,您可以通過子類化進一步自定義文本的外觀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.