Цель-C | NSBezierPath рисовать и раскрашивать в действии

У меня есть собственный класс просмотра с областью отслеживания. Я хочу, чтобы, когда мышь входит в область отслеживания, Безье рисовался цветом, а когда мышь покидала область, Безье исчезал. Чтобы заставить его исчезнуть, я прочитал, что единственный способ - изменить его цвет на цвет фона окна.

Мне удалось добавить область отслеживания, но я не знаю, как нарисовать безье. Если я вставлю код

-(void)drawRect:(NSRect)dirtyRect

он рисуется при запуске приложения, но я этого не хочу. Я пробовал с этим:

@implementation MSBezier

- (void) viewWillMoveToWindow:(NSWindow *)newWindow {
    // Setup a new tracking area when the view is added to the window.
    NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(164.5, 17.5, 270, 65) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void) mouseEntered:(NSEvent*)theEvent {
    NSLog(@"Entered");
    color = [NSColor colorWithCalibratedRed: 0.044 green: 0.813 blue: 0.044 alpha: 0.441];
    CGFloat rectangleCornerRadius = 31;
    NSRect rectangleRect = NSMakeRect(164.5, 17.5, 270, 65);
    NSRect rectangleInnerRect = NSInsetRect(rectangleRect, rectangleCornerRadius, rectangleCornerRadius);
    rectanglePath = NSBezierPath.bezierPath;
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 180 endAngle: 270];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 270 endAngle: 360];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMaxY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 0 endAngle: 90];
    [rectanglePath lineToPoint: NSMakePoint(NSMinX(rectangleRect), NSMaxY(rectangleRect))];
    [rectanglePath closePath];
    [color setStroke];
    [rectanglePath setLineWidth: 3];
    [rectanglePath stroke];

}

- (void) mouseExited:(NSEvent*)theEvent {
    NSLog(@"Exited");
    color = [NSColor colorWithCalibratedRed: 0.949 green: 0.949 blue: 0.949 alpha: 1];
    CGFloat rectangleCornerRadius = 31;
    NSRect rectangleRect = NSMakeRect(164.5, 17.5, 270, 65);
    NSRect rectangleInnerRect = NSInsetRect(rectangleRect, rectangleCornerRadius, rectangleCornerRadius);
    rectanglePath = NSBezierPath.bezierPath;
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 180 endAngle: 270];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 270 endAngle: 360];
    [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMaxY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 0 endAngle: 90];
    [rectanglePath lineToPoint: NSMakePoint(NSMinX(rectangleRect), NSMaxY(rectangleRect))];
    [rectanglePath closePath];
    [color setStroke];
    [rectanglePath setLineWidth: 3];
    [rectanglePath stroke];
}

@end

Но Безье не нарисован.

Спасибо за вашу помощь!

ИЗМЕНИТЬ

Это код до сих пор, который, похоже, ничего не делает:

@implementation MSBezier

bool shouldDrawMyPath = YES;
NSBezierPath *rectanglePath;

- (void)viewWillDraw {

    if (shouldDrawMyPath == YES) {
        NSColor *color = [NSColor colorWithCalibratedRed: 0.044 green: 0.813 blue: 0.044 alpha: 0.441];
        CGFloat rectangleCornerRadius = 31;
        NSRect rectangleRect = NSMakeRect(164.5, 17.5, 270, 65);
        NSRect rectangleInnerRect = NSInsetRect(rectangleRect, rectangleCornerRadius, rectangleCornerRadius);
        rectanglePath = NSBezierPath.bezierPath;
        [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 180 endAngle: 270];
        [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMinY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 270 endAngle: 360];
        [rectanglePath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(rectangleInnerRect), NSMaxY(rectangleInnerRect)) radius: rectangleCornerRadius startAngle: 0 endAngle: 90];
        [rectanglePath lineToPoint: NSMakePoint(NSMinX(rectangleRect), NSMaxY(rectangleRect))];
        [rectanglePath closePath];
        [color setStroke];
        [rectanglePath setLineWidth: 3];
    } else {
        rectanglePath = nil;
    }

}

- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor clearColor] set];
    NSRectFill(self.bounds);

    if (shouldDrawMyPath == YES) {
        [rectanglePath stroke];
    }
}

- (void) viewWillMoveToWindow:(NSWindow *)newWindow {
    NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(164.5, 17.5, 270, 65) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void) mouseEntered:(NSEvent*)theEvent {
    NSLog(@"Entered");
    shouldDrawMyPath = YES;
    [self setNeedsDisplay:YES];
}

- (void) mouseExited:(NSEvent*)theEvent {
    NSLog(@"Exited");
    shouldDrawMyPath = NO;
    [self setNeedsDisplay:YES];
}

@end

Я уверен, что делаю что-то не так.

ИЗМЕНИТЬ 2

Мне просто нужно было установить цвет в drawRect:. Так:

-(void)drawRect:(NSRect)dirtyRect {
    if (shouldDrawMyPath == YES) {
        NSColor *color = [NSColor colorWithCalibratedRed: 0.044 green: 0.813 blue: 0.044 alpha: 0.441];
        [color setStroke];
        [rectanglePath stroke];
    }
}

person Matteo La Mendola    schedule 24.07.2015    source источник


Ответы (1)


Так что это довольно просто. Вам нужно переставить вещи. Сначала создайте свойство BOOL, например shouldDrawMyPath, по умолчанию оно должно быть НЕТ.

Затем в mouseEntered: установите для него значение YES. Вызовите self setNeedsDisplay:YES.

Затем, mouseExited: установите для этого параметра NO Call self setNeedsDisplay:YES

Добавьте свойство NSBezierPath. In viewWillDraw If shouldDrawMyPath == YES Настройте свой путь Безье. В противном случае установите его равным нулю (я предполагаю, что ваше представление может изменить размер в любое время). Если ваше представление никогда не изменяет размер, вы можете создать путь один раз.

В drawRect Сначала очистите доску, особенно если ваш вид может изменять размер. [[NSColor clearColor] установлен]; NSRectFill(self.bounds);

Нарисуйте что-нибудь всегда там, если что.

If shouldDrawMyPath == YES Заполните и/или обведите контур. Else Сделайте любой другой рисунок без контура.

Если вы правильно настроите область отслеживания, это должно помочь вам.

В зависимости от специфики всегда есть оптимизации.

Никогда не рисуйте вне drawRect, если вы не знаете, что делаете.

Держите свой код drawRect простым.

Рисуйте только то, что вам нужно, когда вам нужно. (Вы еще не там, но есть много оптимизаций, которые можно сделать, чтобы сделать недействительными и рисовать только определенные прямоугольники)

person uchuugaka    schedule 24.07.2015
comment
Сначала спасибо! Я сделал все, что вы мне предложили, но в представлении ничего не отображается, может быть, мне следует опубликовать код? Возможно, я что-то не так понял... - person Matteo La Mendola; 24.07.2015
comment
Я отредактировал сообщение с новым кодом, если вы хотите взглянуть. - person Matteo La Mendola; 24.07.2015
comment
Я поигрался с кодом и понял, как заставить его работать. Спасибо! - person Matteo La Mendola; 24.07.2015
comment
Я полагал, что ты получишь это. У вас было достаточно правильных идей в неправильных местах. - person uchuugaka; 25.07.2015