Какой предпочтительный / рекомендуемый способ нарисовать линию в NSView-drawRect: метод? - PullRequest
9 голосов
/ 07 мая 2011

Я не смог найти ни одного примитива для рисования линий в Какао на уровне NSView. Единственное, что я нашел, это NSBezierPath. Это предпочтительный способ? Или есть другой способ, который я не смог обнаружить?

Ответы [ 4 ]

14 голосов
/ 08 мая 2011

NSBezierPath именно то, что вы должны использовать. Если вы просто хотите нарисовать прямую линию от одной точки к другой, используйте метод класса:

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

8 голосов
/ 07 мая 2011

Какао использует неявный стек рисования и модель аннулирования.В вашем NSView, когда состояние изменяется, что заставляет представление рисовать по-другому, вы вызываете - [self setNeedsDisplay:], чтобы сообщить системе рисования, что вам нужно перерисовать.В какой-то момент в очень ближайшем будущем, фактически в конце текущего цикла событий, будет вызван метод drawRect: вашего представления.Это ваша возможность нарисовать что угодно.

Существует неявный стек фокуса, что означает, что когда вызывается drawRect: ваш вид, рисование фокусируется на границах вашего вида в окне и ограничивается им.in. Затем вы можете вызывать такие функции, как [[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 голосов
/ 21 мая 2011

Я попробовал пример, приведенный Джоном, и обнаружил, что мне нужно добавить 2 небольших исправления в приведенный выше пример кода.

  1. вставьте распределитель NSColor в блок инициализации
  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
1 голос
/ 29 мая 2015

Просто чтобы добавить информацию, я стараюсь следить за тем, чтобы графическое состояние сохранялось и восстанавливалось до и после рисования, чтобы все оставалось быстрым.

...