2013-05-30 2 views
1

Я пытаюсь выяснить, как пользовательские кнопки рисования в Cocoa/OSX. Поскольку мое представление выполнено на заказ, я не буду использовать IB и хочу сделать все это в коде. Я создал подкласс NSButtonCell и подкласс NSButton. В подклассе NSButtonCell я переопределяю метод drawBezelWithFrame: inView: и в методе initWithFrame моего подкласса NSButton я использую setCell для установки моего CustomCell в Button. Однако 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. Вы не перекрывая + (класс) cellClass в классе (TWIButton), который является производным от NSButton.

Ниже приведен код после изменения:

@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, так как похоже, что вы используете его только для создания типа ячейки внутри инициализатора. Просто

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

кстати. у вас, вероятно, будет утечка в предыдущих примерах с момента запуска, а затем вызовите setCell, который, вероятно, сохранит свой собственный.

Смежные вопросы