将填充更改为已绘制的NSBezierPath

nan*_*ome 0 cocoa drawing objective-c

我想改变我画的按钮的填充(我将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];
}
Run Code Online (Sandbox Code Playgroud)

我收到一个EXC_BAD_ACCESS信号 我该怎么做?

Mat*_*all 6

原因EXC_BAD_ACCESS是以下行:

aPath = [NSBezierPath bezierPath];
Run Code Online (Sandbox Code Playgroud)

创建一个自动释放的 bezierPath,它将在运行循环的当前迭代结束时释放.为避免错误,您需要将其更改为:

aPath = [[NSBezierPath bezierPath] retain];
Run Code Online (Sandbox Code Playgroud)

但是,你正在从错误的方向接近问题.绘图只能在-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];
}
Run Code Online (Sandbox Code Playgroud)