2013-05-30 6 views
1

Cocoa/OSX에서 Button을 사용자 지정하는 방법을 알아 내려고하고 있습니다. 내 견해가 그려진 맞춤 묘사이므로 IB를 사용하지 않고 코드에서 모두 수행하려고합니다. NSButtonCell의 하위 클래스와 NSButton의 하위 클래스를 만들었습니다. NSButtonCell의 Subclass에서 메소드 drawBezelWithFrame : inView를 재정의하고 서브 클래 싱 된 NSButton의 initWithFrame 메서드에서 setCell을 사용하여 Button에 내 CustomCell을 설정합니다. 그러나 drawBezelWithFrame이 호출되지 않고 이유를 이해할 수 없습니다. 누군가 내가 잘못한 것을 지적 할 수 있습니까? NSButtonCell의사용자 지정 NSButtonCell, drawBezelWithFrame이 호출되지 않았습니다.

서브 클래스 : NSButton의

#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 

서브 클래스 :

#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을 무시하지
  3. .

    @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

이니셜 라이저 내에서 Cell 유형을 인스턴스화하는 용도로만 사용되므로 NSButton 하위 클래스를 사용할 수 없습니다. 간단히

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

btw. 이전 예제에서 init을 호출 한 다음 setCell을 호출 할 때 자체 보유 가능성이있는 호출이 누출 될 수 있습니다.