簡體   English   中英

如何子類化UI元素,如UILabel,UIButton

[英]How to Subclass UI elements like UILabel, UIButton

我在CustomLabel classCustomLabel classUILabel 當我嘗試使用簡單的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM