Objective c 重新绘制NSBezierPath

Objective c 重新绘制NSBezierPath,objective-c,drawing,nsbezierpath,Objective C,Drawing,Nsbezierpath,这就是我用贝塞尔路径画一个类似popover的窗口的方式。布尔值bAbajo使图形窗口指向上方。如果不是bAbajo,则指向上方: - (void)drawRect:(NSRect)dirtyRect { NSRect contentRect = NSInsetRect([self bounds], LINE_THICKNESS, LINE_THICKNESS); NSBezierPath *path = [NSBezierPath bezierPath]; if (_b

这就是我用贝塞尔路径画一个类似popover的窗口的方式。布尔值bAbajo使图形窗口指向上方。如果不是bAbajo,则指向上方:

- (void)drawRect:(NSRect)dirtyRect
{
    NSRect contentRect = NSInsetRect([self bounds], LINE_THICKNESS, LINE_THICKNESS);
    NSBezierPath *path = [NSBezierPath bezierPath];
    if (_bAbajo)
    {
      [path removeAllPoints];
      [path moveToPoint:NSMakePoint(_arrowX, NSMinY(contentRect))];
      [path lineToPoint:NSMakePoint(_arrowX + ARROW_WIDTH / 2, NSMinY(contentRect) + ARROW_HEIGHT)];
      [path lineToPoint:NSMakePoint(NSMaxX(contentRect) - CORNER_RADIUS, NSMinY(contentRect) + ARROW_HEIGHT)];
      NSPoint bottomRightCorner = NSMakePoint(NSMaxX(contentRect), NSMinY(contentRect) + ARROW_HEIGHT);
      [path curveToPoint:NSMakePoint(NSMaxX(contentRect), NSMinY(contentRect) + ARROW_HEIGHT + CORNER_RADIUS)
         controlPoint1:bottomRightCorner controlPoint2:bottomRightCorner];
      [path lineToPoint:NSMakePoint(NSMaxX(contentRect), NSMaxY(contentRect) - CORNER_RADIUS)];
      NSPoint topRightCorner = NSMakePoint(NSMaxX(contentRect), NSMaxY(contentRect));
      [path curveToPoint:NSMakePoint(NSMaxX(contentRect) - CORNER_RADIUS, NSMaxY(contentRect) + CORNER_RADIUS) controlPoint1:topRightCorner controlPoint2:topRightCorner];
      [path lineToPoint:NSMakePoint(NSMinX(contentRect) + CORNER_RADIUS, NSMaxY(contentRect) + CORNER_RADIUS)];
      NSPoint topLeftCorner = NSMakePoint(NSMinX(contentRect), NSMaxY(contentRect));
      [path curveToPoint:NSMakePoint(NSMinX(contentRect), NSMaxY(contentRect) - CORNER_RADIUS) controlPoint1:topLeftCorner controlPoint2:topLeftCorner];
      [path lineToPoint:NSMakePoint(NSMinX(contentRect), NSMinY(contentRect) + CORNER_RADIUS + ARROW_HEIGHT)];
      NSPoint bottomLeftCorner = NSMakePoint(NSMinX(contentRect), NSMinY(contentRect) + ARROW_HEIGHT);
      [path curveToPoint:NSMakePoint(NSMinX(contentRect) + CORNER_RADIUS, NSMinY(contentRect) + ARROW_HEIGHT) controlPoint1:bottomLeftCorner controlPoint2:bottomLeftCorner];
      [path lineToPoint:NSMakePoint(_arrowX - ARROW_WIDTH/2, NSMinY(contentRect) + ARROW_HEIGHT)];
    }
    else
    {
      [path removeAllPoints];
      [path moveToPoint:NSMakePoint(_arrowX, NSMaxY(contentRect))];
      [path lineToPoint:NSMakePoint(_arrowX + ARROW_WIDTH / 2, NSMaxY(contentRect) - ARROW_HEIGHT)];
      [path lineToPoint:NSMakePoint(NSMaxX(contentRect) - CORNER_RADIUS, NSMaxY(contentRect) - ARROW_HEIGHT)];
      NSPoint topRightCorner = NSMakePoint(NSMaxX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT);
      [path curveToPoint:NSMakePoint(NSMaxX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT - CORNER_RADIUS)
           controlPoint1:topRightCorner controlPoint2:topRightCorner];
      [path lineToPoint:NSMakePoint(NSMaxX(contentRect), NSMinY(contentRect) + CORNER_RADIUS)];
      NSPoint bottomRightCorner = NSMakePoint(NSMaxX(contentRect), NSMinY(contentRect));
      [path curveToPoint:NSMakePoint(NSMaxX(contentRect) - CORNER_RADIUS, NSMinY(contentRect))
           controlPoint1:bottomRightCorner controlPoint2:bottomRightCorner];
      [path lineToPoint:NSMakePoint(NSMinX(contentRect) + CORNER_RADIUS, NSMinY(contentRect))];
      [path curveToPoint:NSMakePoint(NSMinX(contentRect), NSMinY(contentRect) + CORNER_RADIUS)
           controlPoint1:contentRect.origin controlPoint2:contentRect.origin];
      [path lineToPoint:NSMakePoint(NSMinX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT - CORNER_RADIUS)];
      NSPoint topLeftCorner = NSMakePoint(NSMinX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT);
      [path curveToPoint:NSMakePoint(NSMinX(contentRect) + CORNER_RADIUS, NSMaxY(contentRect) - ARROW_HEIGHT)
           controlPoint1:topLeftCorner controlPoint2:topLeftCorner];
      [path lineToPoint:NSMakePoint(_arrowX - ARROW_WIDTH / 2, NSMaxY(contentRect) - ARROW_HEIGHT)];
    }
    [path closePath];
    [[NSColor colorWithDeviceWhite:1 alpha:FILL_OPACITY] setFill];
    [path fill];
    //[NSGraphicsContext saveGraphicsState];

    NSBezierPath *clip = [NSBezierPath bezierPathWithRect:[self bounds]];
    [clip appendBezierPath:path];
    [clip addClip];

    [path setLineWidth:LINE_THICKNESS * 2];
    [[NSColor whiteColor] setStroke];
    [path stroke];

    [NSGraphicsContext restoreGraphicsState];
}

在第一次调用drawRect时,一切正常,根据bAbajo布尔值的不同,绘图将按其应有的方式进行。之后,如果我再次使用相反的值bAbajo调用drawRect,则会执行正确的代码(bAbajo具有预期的值,通过使用断点进行调试,我可以看到它正在drawRect内执行正确的代码),但窗口不会用新的NSBezierPath*路径更新。有什么帮助吗?

事实上,Rob间接地给了我答案,我没有在设置bAbajo后调用setNeedsDisplay。

如果在进行任何绘图之前清除窗口会发生什么情况?你说的“如果我再次调用drawRect”是什么意思?你从不直接调用drawRect。你的意思是“当系统调用drawRect时,在我调用setNeedsDisplay之后?”是的,你是对的,我的意思是“当系统调用setNeedsDisplay之后调用它时”