2013-05-30 50 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。