NSBezierPath在动作上绘制和上色



我有一个带有跟踪区域的自定义视图类。我想要的是,当鼠标进入跟踪区域时,绘制带有颜色的贝塞尔曲线,当鼠标退出该区域时,贝塞尔曲线消失。为了让它消失,我读到唯一的方法是改变它的颜色与窗口的背景色。

我设法添加跟踪区域,但我不知道如何绘制bezier。如果我把代码放到

-(void)drawRect:(NSRect)dirtyRect

在应用启动时绘制,但我不想这样。我试过了:

@implementation MSBezier
- (void) viewWillMoveToWindow:(NSWindow *)newWindow {
    // Setup a new tracking area when the view is added to the window.
    NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(164.5, 17.5, 270, 65) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}
- (void) mouseEntered:(NSEvent*)theEvent {
    NSLog(@"Entered");
    color = [NSColor colorWithCalibratedRed: 0.044 green: 0.813 blue: 0.044 alpha: 0.441];
    CGFloat rectangleCornerRadius = 31;
    NSRect rectangleRect = NSMakeRect(164.5, 17.5, 270, 65);
    NSRect rectangleInnerRect = NSInsetRect(rectangleRect, rectangleCornerRadius, rectangleCornerRadius);
    rectanglePath = NSBezierPath.bezierPath;
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 180 endAngle: 270];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 270 endAngle: 360];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMaxY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 0 endAngle: 90];
    [rectanglePath lineToPoint: NSMakePoint(NSMinX(rectangleRect), NSMaxY(rectangleRect))];
    [rectanglePath closePath];
    [color setStroke];
    [rectanglePath setLineWidth: 3];
    [rectanglePath stroke];
}
- (void) mouseExited:(NSEvent*)theEvent {
    NSLog(@"Exited");
    color = [NSColor colorWithCalibratedRed: 0.949 green: 0.949 blue: 0.949 alpha: 1];
    CGFloat rectangleCornerRadius = 31;
    NSRect rectangleRect = NSMakeRect(164.5, 17.5, 270, 65);
    NSRect rectangleInnerRect = NSInsetRect(rectangleRect, rectangleCornerRadius, rectangleCornerRadius);
    rectanglePath = NSBezierPath.bezierPath;
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 180 endAngle: 270];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 270 endAngle: 360];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMaxY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 0 endAngle: 90];
    [rectanglePath lineToPoint: NSMakePoint(NSMinX(rectangleRect), NSMaxY(rectangleRect))];
    [rectanglePath closePath];
    [color setStroke];
    [rectanglePath setLineWidth: 3];
    [rectanglePath stroke];
}
@end

但是贝塞尔曲线没有画出来。

谢谢你的帮助!

编辑@uchuugaka

这是到目前为止的代码,似乎没有做任何事情:

@implementation MSBezier
bool shouldDrawMyPath = YES;
NSBezierPath *rectanglePath;
- (void)viewWillDraw {
    if (shouldDrawMyPath == YES) {
        NSColor *color = [NSColor colorWithCalibratedRed: 0.044 green: 0.813 blue: 0.044 alpha: 0.441];
        CGFloat rectangleCornerRadius = 31;
        NSRect rectangleRect = NSMakeRect(164.5, 17.5, 270, 65);
        NSRect rectangleInnerRect = NSInsetRect(rectangleRect, rectangleCornerRadius, rectangleCornerRadius);
        rectanglePath = NSBezierPath.bezierPath;
        [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 180 endAngle: 270];
        [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 270 endAngle: 360];
        [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMaxY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 0 endAngle: 90];
        [rectanglePath lineToPoint: NSMakePoint(NSMinX(rectangleRect), NSMaxY(rectangleRect))];
        [rectanglePath closePath];
        [color setStroke];
        [rectanglePath setLineWidth: 3];
    } else {
        rectanglePath = nil;
    }
}
- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor clearColor] set];
    NSRectFill(self.bounds);
    if (shouldDrawMyPath == YES) {
        [rectanglePath stroke];
    }
}
- (void) viewWillMoveToWindow:(NSWindow *)newWindow {
    NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(164.5, 17.5, 270, 65) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}
- (void) mouseEntered:(NSEvent*)theEvent {
    NSLog(@"Entered");
    shouldDrawMyPath = YES;
    [self setNeedsDisplay:YES];
}
- (void) mouseExited:(NSEvent*)theEvent {
    NSLog(@"Exited");
    shouldDrawMyPath = NO;
    [self setNeedsDisplay:YES];
}
@end

我肯定我做错了什么。

编辑2

我只需要在drawRect:中设置颜色。所以:

-(void)drawRect:(NSRect)dirtyRect {
    if (shouldDrawMyPath == YES) {
        NSColor *color = [NSColor colorWithCalibratedRed: 0.044 green: 0.813 blue: 0.044 alpha: 0.441];
        [color setStroke];
        [rectanglePath stroke];
    }
}

这很简单。你需要重新安排。首先创建一个BOOL属性,如shouldDrawMyPath这应该默认为NO。

下一步,在mouseenter中:设置为YES调用self setNeedsDisplay:YES

其次,mouseExited:设置为NO调用self setNeedsDisplay:YES

添加NSBezierPath属性。在viewWillDraw如果shouldDrawMyPath == YES设置bezier路径。否则将其设为nil(我假设你的视图可能随时调整大小)如果你的视图从不调整大小,你可以只创建一次路径。

绘制矩形首先要清理黑板,尤其是如果你的视图可以调整大小。[[NSColor clearColor] set];NSRectFill (self.bounds);

总是在那里画任何东西。

如果shouldDrawMyPath == YES填充和/或描边你的路径。其他的在没有路径的情况下画其它图。

只要你正确设置你的跟踪区域,这应该让你继续。

根据具体情况,总是有优化。

永远不要在drawRect之外绘制,除非你知道你在做什么。

保持你的drawRect代码简单。

只在你需要的时候画你需要的。(你还没有到那里,但有很多优化可以做的无效,只绘制特定的矩形)

相关内容

  • 没有找到相关文章

最新更新