2013-03-18 1 views
0

하위 클래스를 만들려고하는데 NSButtonCell 하위 클래스를 사용하지만 코드에서 그렇게 할 수 없습니다!프로그래밍 방식으로 사용자 지정 NSButtonCell NSButton의 하위 클래스를 할당하는 방법?

이것은 내가 IB의 버튼을 생성하고 IB에 직접 자신의 휴대 클래스를 설정 한 경우의 내 NSButonCell 서브 클래스가 잘 작동입니다 :

#import "MyCustomCell.h" 

@implementation MyCustomCell 

- (void)drawImage:(NSImage*)image withFrame:(NSRect)frame inView:(NSView*)controlView 
{ 
    NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; 
    CGContextRef contextRef = [ctx graphicsPort]; 

    NSData *data = [image TIFFRepresentation]; 
    CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)data, NULL); 
    if(source) { 
     CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); 
     CFRelease(source); 

     CGContextSaveGState(contextRef); 
     { 
      NSRect rect = NSOffsetRect(frame, 0.0f, 1.0f); 
      CGFloat white = [self isHighlighted] ? 0.2f : 0.35f; 
      CGContextClipToMask(contextRef, NSRectToCGRect(rect), imageRef); 
      [[NSColor colorWithDeviceWhite:white alpha:1.0f] setFill]; 
      NSRectFill(rect); 
     } 
     CGContextRestoreGState(contextRef); 

     CGContextSaveGState(contextRef); 
     { 
      NSRect rect = frame; 
      CGContextClipToMask(contextRef, NSRectToCGRect(rect), imageRef); 
      [[NSColor colorWithDeviceWhite:0.1f alpha:1.0f] setFill]; 
      NSRectFill(rect); 
     } 
     CGContextRestoreGState(contextRef);   

     CFRelease(imageRef); 
    } 
} 

- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView 
{ 
    NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; 

    CGFloat roundedRadius = 3.0f; 

    BOOL outer = YES; 
    BOOL background = YES; 
    BOOL stroke = YES; 
    BOOL innerStroke = YES; 

    if(outer) { 
     [ctx saveGraphicsState]; 
     NSBezierPath *outerClip = [NSBezierPath bezierPathWithRoundedRect:frame xRadius:roundedRadius yRadius:roundedRadius]; 
     [outerClip setClip]; 

     NSGradient *outerGradient = [[NSGradient alloc] initWithColorsAndLocations: 
           [NSColor colorWithDeviceWhite:0.20f alpha:1.0f], 0.0f, 
           [NSColor colorWithDeviceWhite:0.21f alpha:1.0f], 1.0f, 
           nil]; 

     [outerGradient drawInRect:[outerClip bounds] angle:90.0f]; 
     [outerGradient release]; 
     [ctx restoreGraphicsState]; 
    } 

    if(background) { 
     [ctx saveGraphicsState]; 
     NSBezierPath *backgroundPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2.0f, 2.0f) xRadius:roundedRadius yRadius:roundedRadius]; 
     [backgroundPath setClip]; 

     NSGradient *backgroundGradient = [[NSGradient alloc] initWithColorsAndLocations: 
             [NSColor colorWithDeviceWhite:0.17f alpha:1.0f], 0.0f, 
             [NSColor colorWithDeviceWhite:0.20f alpha:1.0f], 0.12f, 
             [NSColor colorWithDeviceWhite:0.27f alpha:1.0f], 0.5f, 
             [NSColor colorWithDeviceWhite:0.30f alpha:1.0f], 0.5f, 
             [NSColor colorWithDeviceWhite:0.42f alpha:1.0f], 0.98f, 
             [NSColor colorWithDeviceWhite:0.50f alpha:1.0f], 1.0f, 
             nil]; 

     [backgroundGradient drawInRect:[backgroundPath bounds] angle:270.0f]; 
     [backgroundGradient release]; 
     [ctx restoreGraphicsState]; 
    } 

    if(stroke) { 
     [ctx saveGraphicsState]; 
     [[NSColor colorWithDeviceWhite:0.12f alpha:1.0f] setStroke]; 
     [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1.5f, 1.5f) xRadius:roundedRadius yRadius:roundedRadius] stroke]; 
     [ctx restoreGraphicsState]; 
    } 

    if(innerStroke) { 
     [ctx saveGraphicsState]; 
     [[NSColor colorWithDeviceWhite:1.0f alpha:0.05f] setStroke]; 
     [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2.5f, 2.5f) xRadius:roundedRadius yRadius:roundedRadius] stroke]; 
     [ctx restoreGraphicsState];   
    } 

    if([self isHighlighted]) { 
     [ctx saveGraphicsState]; 
     [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2.0f, 2.0f) xRadius:roundedRadius yRadius:roundedRadius] setClip]; 
     [[NSColor colorWithCalibratedWhite:0.0f alpha:0.35] setFill]; 
     NSRectFillUsingOperation(frame, NSCompositeSourceOver); 
     [ctx restoreGraphicsState]; 
    } 
} 

@end 

나는이 NSButtonCell

#import "myButton.h" 
#import "MyCustomCell.h" 

@implementation myButton 

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     [self setCell:[[MyCustomCell alloc] init]]; 
     self.image = [NSImage imageNamed:@"add"]; 

    } 

    return self; 
} 

@end 
를 사용하여 사용자 정의 NSButton sublclass을 만들

하지만 내보기에서이 버튼을 만들면 버튼 모양이 기본값이며 NSButtonCell 하위 클래스의 사용자 정의 스타일이 아닙니다. IB에서 셀을 설정하면 코드에서 작동하지 만 훌륭합니다. 누구든지 그 문제를 해결할 생각이 있습니까? 감사!

+0

-initWithNibName : bundle : [self setCell : [[MyCustomCell alloc] initinitWithNibName : @ "nibName"번들 : nil]]과 같은 코드에서 MyCustomCell 초기화를 시도 했습니까? ? –

+0

nib o xib를 사용하고 싶지 않습니다. 코드에 모두 할당하지 않겠습니까 – Luca

+0

myButton 클래스에 중단 점을 설정하면'-initWithFrame :'가 호출됩니까? 이것은 잘 작동해야합니다. – gaige

답변

1

이 문제를 해결하는 방법을 알고 있습니다.

setBezelStyle을 호출하는 버튼에 베젤 스타일을 설정해야합니다. 이 코드 라인은 이미지가 거꾸로 된 것을 제외하고는 모두 훌륭하게 작동합니다.

0

cellClass 클래스 메서드를 사용해 보셨습니까?

+ (Class)cellClass { 
    return MyCustomCell.class; 
} 
+0

그래, 나는 또한 'cellClass' 메서드를 사용하려고 시도했지만 여전히 작동하지 않습니다! 유일한 해결책은 XIB 파일을 사용하는 것이지만 실제로는 이상한 상황입니다. 코드로이를 수행 할 수 있어야합니다. – Luca