2011-05-07 77 views

回答

7

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

有一个隐含的焦点堆栈,这意味着当您调用view的drawRect:时,绘图会聚焦在您的视图的边界上并将其剪裁到其所在的窗口中。然后可以调用函数,如[[NSColor redColor]组];和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 

的视图应该绘制一条对角线,它被点击,每次行应该改变颜色。

+0

darRect方法中的第二个moveToPoint调用应该是lineToPoint调用。 – 2012-10-18 05:24:41

+0

完成! - 谢谢。 – 2012-10-18 05:33:45

13

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

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

2

我试图通过乔恩给出的例子,我发现我需要2条小的修改添加到代码示例以上。

  1. ,使之成为一个lineToPoint

一旦我固定这一点,我发现代码片段非常有用的插入NSColor的分配器到初始块

  • 改变第二moveToPoint。 注意:您可能还需要释放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 
    
  • 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] 
    
    } 
    
    +1

    为什么这会让事情变得活泼? – 2015-07-24 05:26:45

    相关问题