2015-07-24 1 views
2

J'ai une classe de vue personnalisée avec une zone de suivi. Je veux que, quand la souris entre dans la zone de suivi, un bezier est dessiné avec une couleur, et quand la souris quitte la zone, le bezier disparaît. Afin de le faire disparaître, j'ai lu que le seul moyen est de changer sa couleur avec la couleur de fond de la fenêtre.Objectif-C | NSBezierPath dessine et colorie sur l'action

J'ai réussi à ajouter la zone de suivi, mais je ne sais pas comment dessiner le bezier. Si je mets le code dans

-(void)drawRect:(NSRect)dirtyRect 

il est dessiné quand l'application se lance, mais je ne le veux pas. J'ai essayé avec ceci:

@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 

Mais le bezier n'est pas dessiné.

Merci pour votre aide!

EDIT @uchuugaka

Voici le code à ce jour, ce qui ne semble pas faire quoi que ce soit:

@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 

Je suis sûr que je fais quelque chose de mal.

EDIT 2

Je avais juste besoin de définir la couleur dans drawRect:. Donc:

-(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]; 
    } 
} 

Répondre

1

Donc c'est assez simple. Vous devez réorganiser les choses. Créez d'abord une propriété BOOL comme shouldDrawMyPath par défaut.

Ensuite, mouseEntered: ensemble qui YES Appel auto setNeedsDisplay: OUI

Ensuite, mouseExited: que défini NO Appel auto setNeedsDisplay: OUI

Ajouter une propriété NSBezierPath. In viewWillDraw If shouldDrawMyPath == OUI Configurez votre parcours Bézier. Sinon, réglez-le sur (Je suppose que votre vue peut être redimensionnée à tout moment) Si votre vue ne redimensionne jamais, vous pouvez créer le chemin une fois.

In drawRect Commencez par effacer le tableau, en particulier si votre vue peut être redimensionnée. [[NSColor clearColor] set]; NSRectFill (self.bounds); Dessinez n'importe quoi toujours là s'il y a quoi que ce soit.

Si shouldDrawMyPath == OUI Remplissez et/ou masquer votre trajectoire. Sinon Effectuez un autre dessin sans le chemin.

Tant que vous définissez correctement votre zone de suivi, cela devrait vous aider à démarrer.

En fonction des spécificités, il existe toujours des optimisations. Ne jamais dessiner en dehors du drawRect à moins de savoir ce que vous faites.

Gardez votre code de dessin simple.

Ne dessinez que ce dont vous avez besoin quand vous en avez besoin. (Vous n'êtes pas encore là, mais il y a beaucoup d'optimisations qui peuvent être faites pour invalider et ne faire que des retraits particuliers)

+0

Merci d'abord! J'ai fait tout ce que vous m'a suggéré, mais dans la vue ne semble pas bezier, peut-être devrais-je poster le code? Peut-être que j'ai mal compris quelque chose ... –

+0

J'ai modifié le message avec le nouveau code, si vous voulez jeter un coup d'oeil. –

+0

J'ai joué avec le code et j'ai compris comment le faire fonctionner. Merci! –