NSView inconsistent render of custom fonts

Viewed 107

I am using a custom font along with an attributed label for my button and every so often the button seems to be rendered differently to how I expect when opening the NSWindow.

NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:centredStyle,
                       NSParagraphStyleAttributeName,
                       [NSFont fontWithName:@"Raleway-Bold" size:button_size],
                       NSFontAttributeName,
                       _red,
                       NSForegroundColorAttributeName,
                       nil];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"DELETE ALL" attributes:attrs];
[deleteNotifications setAttributedTitle:attributedString];

For some reason that I cannot work out the button is rendered either like (wrong):

enter image description here

or

enter image description here

Notice that the latter (correct) image has the opacity set which the first render seems to neglect and also notice the NSShadow also being rendered differently.


I cannot identify when the button changes all I do know is that it always starts correctly. I have setWantsLayer set to yes after allocating the button:

MyButton *deleteNotifications = [[MyButton alloc] initWithFrame:CGRectMake(window_width / 2 + (p /2), button_y, window_width /2 - p, 25)];
[deleteNotifications setWantsLayer:YES];
[deleteNotifications.layer setOpacity:min_opac];
[deleteNotifications setOpacity_min:min_opac];
[deleteNotifications setButtonType:NSMomentaryChangeButton];

I am also having a similar problem when clicking on a NSTextField object where the font becomes bolder than it has been rendered. (I believe the solution to the button will solve this too)

Before click: enter image description here

After click (focus): enter image description here


MyButton

@interface MyButton: NSButton
@property (strong) NSTrackingArea* trackingArea;
@property float opacity_min;
@end

@implementation MyButton
-(void)mouseEntered:(NSEvent *)theEvent {
    [super resetCursorRects];
    [self addCursorRect:self.bounds cursor:[NSCursor pointingHandCursor]];
    
    CABasicAnimation *flash = [CABasicAnimation animationWithKeyPath:@"opacity"];
    flash.fromValue = [NSNumber numberWithFloat:self.opacity_min];
    
    NSMutableArray *notifications = [[[NSUserDefaults standardUserDefaults] objectForKey:@"notifications"] mutableCopy];
    if((int)[notifications count] != 0){
        flash.toValue = [NSNumber numberWithFloat:1];
    }
    
    flash.duration = 0.2;
    [flash setFillMode:kCAFillModeForwards];
    [flash setRemovedOnCompletion:NO];
    flash.repeatCount = 1;
    [self.layer addAnimation:flash forKey:@"flashAnimation"];
}

-(void)mouseExited:(NSEvent *)theEvent{
    [super resetCursorRects];
    
    CABasicAnimation *flash = [CABasicAnimation animationWithKeyPath:@"opacity"];
    
    NSMutableArray *notifications = [[[NSUserDefaults standardUserDefaults] objectForKey:@"notifications"] mutableCopy];
    if((int)[notifications count] != 0){
        flash.fromValue = [NSNumber numberWithFloat:1];
    }
    
    flash.toValue = [NSNumber numberWithFloat:self.opacity_min];
    flash.duration = 0.2;
    [flash setFillMode:kCAFillModeForwards];
    [flash setRemovedOnCompletion:NO];
    flash.repeatCount = 1;
    [self.layer addAnimation:flash forKey:@"flashAnimation"];
}

-(void)updateTrackingAreas
{
    if(self.trackingArea != nil) {
        [self removeTrackingArea:self.trackingArea];
    }
    
    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
    self.trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
                                                     options:opts
                                                       owner:self
                                                    userInfo:nil];
    
    [self addTrackingArea:self.trackingArea];
}
@end

hunch

I believe it may have something to do with makeKeyAndOrderFront when showing the window.

0 Answers
Related