我想更改我绘制的按钮的填充(我将NSButton子类化)
这是我已经获得的代码:
- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
// Create the Gradient
NSGradient *fillGradient = [[NSGradient alloc] initWithStartingColor:[NSColor lightGrayColor] endingColor:[NSColor darkGrayColor]];
// Create the path
aPath = [NSBezierPath bezierPath];
[aPath moveToPoint:NSMakePoint(10.0, 0.0)];
[aPath lineToPoint:NSMakePoint(85.0, 0.0)];
[aPath lineToPoint:NSMakePoint(85.0, 20.0)];
[aPath lineToPoint:NSMakePoint(10.0, 20.0)];
[aPath lineToPoint:NSMakePoint(0.0, 10.0)];
[aPath lineToPoint:NSMakePoint(10.0, 0.0)];
[fillGradient drawInBezierPath:aPath angle:90.0];
[fillGradient release];
}
- (void)mouseDown:(NSEvent *)theEvent {
NSGradient *fillGradient = [[NSGradient alloc] initWithStartingColor:[NSColor lightGrayColor] endingColor:[NSColor darkGrayColor]];
[fillGradient drawInBezierPath:aPath angle:-90.0];
}
我收到EXC_BAD_ACCESS
信号。我该怎么做?
答案 0 :(得分:6)
EXC_BAD_ACCESS
的原因是以下行:
aPath = [NSBezierPath bezierPath];
创建一个自动释放的 bezierPath,它将在运行循环的当前迭代结束时释放。为避免错误,您需要将其更改为:
aPath = [[NSBezierPath bezierPath] retain];
然而,你正在从错误的方向接近问题。绘图只能在-drawRect:
方法(或仅从-drawRect:
调用的方法)中完成。您应该为您的类创建一个新的mouseDown:
实例变量(例如,称为BOOL
),而不是尝试使用mouseIsDown
方法绘制,并在mouseDown:
中设置该变量。然后使用该布尔值来确定如何填充按钮:
- (void)drawRect:(NSRect)aRect {
NSGradient *fillGradient = nil;
if (mouseIsDown)
fillGradient = [[NSGradient alloc] initWithStartingColor:[NSColor lightGrayColor] endingColor:[NSColor darkGrayColor]];
else
fillGradient = [[NSGradient alloc] initWithStartingColor:[NSColor lightGrayColor] endingColor:[NSColor darkGrayColor]];
// Do the rest of your drawRect method
}
- (void)mouseDown:(NSEvent *)theEvent {
mouseIsDown = YES;
[self setNeedsDisplay:YES];
}
- (void)mouseUp:(NSEvent *)theEvent {
mouseIsDown = NO;
[self setNeedsDisplay:YES];
}
答案 1 :(得分:1)
这与您的问题没有直接关系,但您的问题标题掩盖了我想要解决的错误假设。
将填充更改为已绘制的NSBezierPath
那是不可能的。
在Cocoa中,“fill”是一个动词,而不是像Illustrator或Lineform中的对象的属性。您不设置路径的填充,也不会在以后更改它;你填充路径,你改变的是一些看不见的后备存储中的像素。现实世界的类比是在平坦的玻璃板上设置花键,然后用油漆填充花键边界区域并让它干燥。 “填充”不是样条的属性;这是将油漆浇注到他们定义的形状中的行为。
与此类比,你不能删除或改变你以前做过的填充 - 油漆粘在玻璃上;没有得到它*。实现这种效果的唯一方法是用其他颜色重新填充。如果只想更改现有图形的一部分,可以在填充之前移动样条线(创建新路径)或添加样条线(将交叉子路径添加到现有路径)。
所有这些都适用于所有绘图操作,包括描边路径和绘制光栅图像。文字绘图也是如此,这只是填充和/或抚摸路径的另一种情况。
*好吧,您可能可以通过化学方法或通过刮擦从真实玻璃上除去真正的油漆。没有类比是完美的。 ☺
答案 2 :(得分:0)
创建后保留aPath
,因为在autoreleased
消息发送时它将为mouseDown:
。只需确保release
在您班级dealloc
或其他任何合适的地方{。}}。
请参阅Matt Ball的答案。