我在NSView级别的Cocoa中找不到任何线条图原语。我找到的唯一一件事是NSBezierPath
。这是首选方式吗?还是有另一种我无法发现的方式?
答案 0 :(得分:14)
NSBezierPath
正是您应该使用的。如果您只想从一个点到另一个点绘制直线,请使用类方法:
+strokeLineFromPoint:(NSPoint)point1 toPoint:(NSPoint)point2
答案 1 :(得分:8)
Cocoa使用隐式绘图堆栈和失效模型。在NSView中,当状态更改会导致视图绘制方式不同时,您调用 - [self setNeedsDisplay:]告诉绘图系统您需要重绘。在不久的将来的某个时刻,实际上是当前事件循环的结束,将调用您的视图的drawRect:方法。这是你抽出任何你想要的东西的机会。
有一个隐含的焦点堆栈,这意味着当你的视图的drawRect:被调用时,绘图会聚焦并剪切到你所在窗口中视图的边界。然后你可以调用像[[NSColor redColor] set]这样的函数;和NSRectFill([self bounds]);
以下是一个例子:
@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
视图应绘制一条对角线,每次单击该线条时,该线条应改变颜色。
答案 2 :(得分:2)
我尝试了Jon给出的示例,发现我需要在上面的代码示例中添加2个小修补程序。
一旦我解决了这个问题,我发现代码snippit非常有用。 注意:您可能还需要释放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
答案 3 :(得分:1)
只是为了添加一些信息,我养成了确保在绘图前后保存和恢复图形状态的习惯,以保持活力。
- (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]
}