在 NSView-drawRect: 方法中绘制线条的首选/推荐方法是什么?

发布于 2024-11-05 07:27:42 字数 94 浏览 4 评论 0原文

我在 Cocoa 的 NSView 级别找不到任何线条绘制原语。我唯一找到的是NSBezierPath。这是首选方式吗?还是还有其他我没发现的方法?

I couldn't found any line drawing primitive in Cocoa at NSView level. The only thing I've been found is NSBezierPath. Is this a preferred way? Or is there another way which I couldn't discovered?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一笑百媚生 2024-11-12 07:27:42

NSBezierPath 正是您应该使用的。如果您只想从一个点到另一个点绘制一条直线,请使用类方法:

+StrokeLineFromPoint:(NSPoint)point1 toPoint:(NSPoint)point2

NSBezierPath is exactly what you should be using. If you just want to draw a straight line from one point to another, use the class method:

+strokeLineFromPoint:(NSPoint)point1 toPoint:(NSPoint)point2

一身仙ぐ女味 2024-11-12 07:27:42

Cocoa 使用隐式绘图堆栈和失效模型。在你的 NSView 中,当状态改变导致视图以不同的方式绘制时,你调用 -[self setNeedsDisplay:] 来告诉绘图系统你需要重新绘制。在不久的将来的某个时刻,实际上是当前事件循环的结束,您的视图的drawRect:方法将被调用。这是你画任何你想画的东西的机会。

有一个隐式焦点堆栈,这意味着当调用视图的drawRect:时,绘图将集中在其所在窗口中的视图边界上并剪切到视图的边界。然后,您可以调用诸如 [[NSColor redColor] set]; 之类的函数和 NSRectFill([自身边界]);

下面是一个示例:

@interface MyView : NSView {
    @private
    NSColor *lineColor; 
    NSInteger clickCount;
}
@end

@implementation MyView
- (void)setLineColor:(NSColor *)color {
    if (color != lineColor) {
        [lineColor release];
        lineColor = [color copy];
        [self setNeedsDisplay:YES]; /// We changed what we'd draw, invalidate our drawing.
    }
}
- (void)mouseDown:(NSEvent *)mouseDown {
    clickCount = (clickCount == 6) ? 0 : (clickCount + 1);
    CGFloat hue = clickCount / 6.0; 
    [self setLineColor:[NSColor colorWithCalibratedHue:hue saturation:1.0 brightness:1.0 alpha:1.0]];
}

- (void)drawRect:(NSRect)dirtyRect {
    NSBezierPath *line = [NSBezierPath bezierPath];
    [line moveToPoint:NSMakePoint(NSMinX([self bounds]), NSMinY([self bounds]))];
    [line lineToPoint:NSMakePoint(NSMaxX([self bounds]), NSMaxY([self bounds]))];
    [line setLineWidth:5.0]; /// Make it easy to see
    [[self lineColor] set]; /// Make future drawing the color of lineColor.
    [line stroke];
}
@end

视图应绘制一条对角线,每次单击该对角线时,该线都应改变颜色。

Cocoa uses an implicit drawing stack, and an invalidation model. In your NSView, when state changes that would cause the view to draw differently, you invoke -[self setNeedsDisplay:] to tell the drawing system that you need to be redrawn. At some point in very near future, actually the end of the current event loop, your view's drawRect: method will be called. That's your opportunity to draw anything you'd like.

There's an implicit focus stack, meaning that when your view's drawRect: is called, drawing is focused on and clipped to the bounds of your view in the window it is in. You can then call functions like [[NSColor redColor] set]; and NSRectFill([self bounds]);

Here's an example:

@interface MyView : NSView {
    @private
    NSColor *lineColor; 
    NSInteger clickCount;
}
@end

@implementation MyView
- (void)setLineColor:(NSColor *)color {
    if (color != lineColor) {
        [lineColor release];
        lineColor = [color copy];
        [self setNeedsDisplay:YES]; /// We changed what we'd draw, invalidate our drawing.
    }
}
- (void)mouseDown:(NSEvent *)mouseDown {
    clickCount = (clickCount == 6) ? 0 : (clickCount + 1);
    CGFloat hue = clickCount / 6.0; 
    [self setLineColor:[NSColor colorWithCalibratedHue:hue saturation:1.0 brightness:1.0 alpha:1.0]];
}

- (void)drawRect:(NSRect)dirtyRect {
    NSBezierPath *line = [NSBezierPath bezierPath];
    [line moveToPoint:NSMakePoint(NSMinX([self bounds]), NSMinY([self bounds]))];
    [line lineToPoint:NSMakePoint(NSMaxX([self bounds]), NSMaxY([self bounds]))];
    [line setLineWidth:5.0]; /// Make it easy to see
    [[self lineColor] set]; /// Make future drawing the color of lineColor.
    [line stroke];
}
@end

The view should draw a diagonal line, and each time it is clicked the line should change color.

云雾 2024-11-12 07:27:42

我尝试了 Jon 给出的示例,发现我需要对上面的代码示例添加 2 个小修复。

  1. 将 NSColor 的分配器插入 init 块中,
  2. 更改第二个 moveToPoint ,使其成为 lineToPoint

一旦我解决了这个问题,我发现代码片段非常有用。
注意:您可能还需要取消分配 NSColor。

@interface PropertyPropagateView : NSView {
@private
    NSColor *lineColor; 
    NSInteger clickCount;  
}

@end


@implementation PropertyPropagateView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        lineColor=[NSColor blueColor];
    }

    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)setLineColor:(NSColor *)color {
    if (color != lineColor) {
        [lineColor release];
        lineColor = [color copy];
        [self setNeedsDisplay:YES]; /// We changed what we'd draw, invalidate our drawing.
    }
}
- (void)mouseDown:(NSEvent *)mouseDown {
    clickCount = (clickCount == 6) ? 0 : (clickCount + 1);
    CGFloat hue = clickCount / 6.0; 
    [self setLineColor:[NSColor colorWithCalibratedHue:hue saturation:1.0 brightness:1.0 alpha:1.0]];
}

- (void)drawRect:(NSRect)dirtyRect
{

    NSBezierPath *line = [NSBezierPath bezierPath];
    [line moveToPoint:NSMakePoint(NSMinX([self bounds]), NSMinY([self bounds]))];
    [line lineToPoint:NSMakePoint(NSMaxX([self bounds]), NSMaxY([self bounds]))];
    [line setLineWidth:5.0]; /// Make it easy to see
    [lineColor set]; /// Make future drawing the color of lineColor.

    [line stroke];
}

@end

I tried the example given by Jon and found that i needed to add 2 minor fixes to the code sample above.

  1. insert an allocator of the NSColor into the init block
  2. change the second moveToPoint so that it becomes a lineToPoint

Once i fixed this, i found the code snippit very useful.
NOTE: you probably need to dealloc the NSColor as well.

@interface PropertyPropagateView : NSView {
@private
    NSColor *lineColor; 
    NSInteger clickCount;  
}

@end


@implementation PropertyPropagateView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        lineColor=[NSColor blueColor];
    }

    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)setLineColor:(NSColor *)color {
    if (color != lineColor) {
        [lineColor release];
        lineColor = [color copy];
        [self setNeedsDisplay:YES]; /// We changed what we'd draw, invalidate our drawing.
    }
}
- (void)mouseDown:(NSEvent *)mouseDown {
    clickCount = (clickCount == 6) ? 0 : (clickCount + 1);
    CGFloat hue = clickCount / 6.0; 
    [self setLineColor:[NSColor colorWithCalibratedHue:hue saturation:1.0 brightness:1.0 alpha:1.0]];
}

- (void)drawRect:(NSRect)dirtyRect
{

    NSBezierPath *line = [NSBezierPath bezierPath];
    [line moveToPoint:NSMakePoint(NSMinX([self bounds]), NSMinY([self bounds]))];
    [line lineToPoint:NSMakePoint(NSMaxX([self bounds]), NSMaxY([self bounds]))];
    [line setLineWidth:5.0]; /// Make it easy to see
    [lineColor set]; /// Make future drawing the color of lineColor.

    [line stroke];
}

@end
临风闻羌笛 2024-11-12 07:27:42

只是为了添加一些信息,我养成了确保在绘制之前和之后保存和恢复图形状态的习惯,以保持工作顺利。

- (void)drawRect:(NSRect)dirtyRect {

    [[NSGraphicsContext currentContext] saveGraphicsState]

    NSBezierPath *line = [NSBezierPath bezierPath];
    [line moveToPoint:NSMakePoint(NSMinX([self bounds]), NSMinY([self bounds]))];
    [line lineToPoint:NSMakePoint(NSMaxX([self bounds]), NSMaxY([self bounds]))];
    [line setLineWidth:5.0]; /// Make it easy to see
    [[self lineColor] set]; /// Make future drawing the color of lineColor.
    [line stroke];

    [[NSGraphicsContext currentContext] restoreGraphicsState]

}

Just to add some info, I make a habit of making sure the graphics state is saved and restored before and after drawing, to keep things zippy.

- (void)drawRect:(NSRect)dirtyRect {

    [[NSGraphicsContext currentContext] saveGraphicsState]

    NSBezierPath *line = [NSBezierPath bezierPath];
    [line moveToPoint:NSMakePoint(NSMinX([self bounds]), NSMinY([self bounds]))];
    [line lineToPoint:NSMakePoint(NSMaxX([self bounds]), NSMaxY([self bounds]))];
    [line setLineWidth:5.0]; /// Make it easy to see
    [[self lineColor] set]; /// Make future drawing the color of lineColor.
    [line stroke];

    [[NSGraphicsContext currentContext] restoreGraphicsState]

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文