我'我试图创建一个NSButton
的子类,它也使用NSButtonCell
的子类,但我可以'在代码中执行此操作!
这是我的NSButonCell子类,如果我在IB中创建按钮并直接在IB中设置他的单元格类,那么它的效果很好:
#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
我还创建了一个使用此NSButton
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
但是当我在视图中创建此按钮时,按钮的外观是默认的,而不是NSButtonCell
子类的自定义样式。如果我在IB中设置单元格,那么所有工作都很好但不是代码。有人有想法解决这个问题吗?谢谢!
答案 0 :(得分:1)
我理解如何解决问题。
需要在调用setBezelStyle
的按钮上设置挡板样式。除了图像颠倒之外,所有这些代码都很有效。
答案 1 :(得分:0)
您是否尝试过使用cellClass类方法?
+ (Class)cellClass {
return MyCustomCell.class;
}