2013-05-30 52 views
1

我想弄清楚如何在Cocoa/OSX中自定義繪製按鈕。由於我的視圖是自定義繪製的,因此我不會使用IB並希望在代碼中完成所有操作。我創建了NSButtonCell的一個子類和NSButton的一個子類。在NSButtonCell的子類中,我重寫了方法drawBezelWithFrame:inView:和我的子類NSButton的initWithFrame方法中,我使用setCell在Button中設置我的CustomCell。然而,drawBezelWithFrame不會被調用,我不明白爲什麼。有人能指出我做錯了什麼或我在這裏錯過了什麼嗎?自定義NSButtonCell,drawBezelWithFrame不叫

NSButtonCell的子類:

#import "TWIButtonCell.h" 

@implementation TWIButtonCell 

-(void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView 
{ 
    //// General Declarations 
[[NSGraphicsContext currentContext] saveGraphicsState]; 

    //// Color Declarations 
    NSColor* fillColor = [NSColor colorWithCalibratedRed: 0 green: 0.59 blue: 0.886 alpha: 1]; 

    //// Rectangle Drawing 
    NSBezierPath* rectanglePath = [NSBezierPath bezierPathWithRect: NSMakeRect(8.5, 7.5, 85, 25)]; 
    [fillColor setFill]; 
    [rectanglePath fill]; 
    [NSGraphicsContext restoreGraphicsState]; 
} 

@end 

NSButton的子類:

#import "TWIButton.h" 
#import "TWIButtonCell.h" 

@implementation TWIButton 

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     TWIButtonCell *cell = [[TWIButtonCell alloc]init]; 
     [self setCell:cell]; 
    } 

    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect 
{ 
    // Drawing code here. 
} 

@end 

用法:

- (void)addSendButton:(NSRect)btnSendRectRect 
{ 
    TWIButton *sendButton = [[TWIButton alloc] initWithFrame:btnSendRectRect]; 
    [self addSubview:sendButton]; 
    [sendButton setTitle:@"Send"]; 
    [sendButton setTarget:self]; 
    [sendButton setAction:@selector(send:)]; 
} 

回答

4

以下是東西似乎是從你的代碼錯過了。

  1. 您還沒有調用[超級的drawRect:dirtyRect]
  2. 您還沒有被從NSButton派生的類(TWIButton)重寫+(類)cellClass

下面是更改後的代碼:

@implementation TWIButton 

    - (id)initWithFrame:(NSRect)frame 
    { 
     self = [super initWithFrame:frame]; 
     if (self) 
     { 
      TWIButtonCell *cell = [[TWIButtonCell alloc]init]; 
      [self setCell:cell]; 
     } 

     return self; 
    } 

    - (void)drawRect:(NSRect)dirtyRect 
    { 
     // Drawing code here. 
     //Changes Added!!! 
    [super drawRect:dirtyRect]; 

    } 

    //Changes Added!!!! 
    + (Class)cellClass 
    { 
     return [TWIButtonCell class]; 
    } 

    @end 

現在保持破發點,在drawBezelWithFrame並檢查它就會被調用。

+0

謝謝你,作品像魅力。 drawRect方法是由XCode模板創建的,他們爲什麼不包含超級調用。 – CaptnCrash

+0

cellClass已在OS X 10.11中棄用。任何想法如何通過避免被棄用的方法來解決它? –

2

有人可能會放棄NSButton的子類,因爲它看起來像只用它來初始化初始值設定項中的Cell類型。 只需

NSButton *button ... 
[button setCell: [[TWIButtonCell alloc] init] autorelease]]; 

btw。自從你初始化之後,你可能會在之前的例子中發現泄漏,然後調用可能有自己的保留的setCell。