Chellange 2 problem


#1

Hello

I am at chellange 2 in this chapter. I have made two BOOL variables (isBold and isItalic). The two checkboxes i have bind to this two values.
Now i have created the accessor methods:

- (void)setIsBold:(BOOL)bold {
    if (bold == YES) {
        NSFontManager *fontManager = [NSFontManager sharedFontManager];
        NSFont *font = [attributes objectForKey:NSFontAttributeName];
        [attributes setObject:[fontManager convertFont:font toHaveTrait:NSBoldFontMask] forKey:NSFontAttributeName];
        NSLog(@"bold");
    }
    else {
        NSFontManager *fontManager = [NSFontManager sharedFontManager];
        NSFont *font = [attributes objectForKey:NSFontAttributeName];
        [attributes setObject:[fontManager convertFont:font toNotHaveTrait:NSBoldFontMask] forKey:NSFontAttributeName];
        NSLog(@"not bold");
    }
    [self setNeedsDisplay:YES];
}

- (BOOL)isBold {
    return isBold;
}

- (void)setIsItalic:(BOOL)italic {
    if (italic == YES) {
        NSFontManager *fontManager = [NSFontManager sharedFontManager];
        NSFont *font = [attributes objectForKey:NSFontAttributeName];
        [attributes setObject:[fontManager convertFont:font toHaveTrait:NSItalicFontMask] forKey:NSFontAttributeName];
        NSLog(@"italic");
    }
    else {
        NSFontManager *fontManager = [NSFontManager sharedFontManager];
        NSFont *font = [attributes objectForKey:NSFontAttributeName];
        [attributes setObject:[fontManager convertFont:font toNotHaveTrait:NSItalicFontMask] forKey:NSFontAttributeName];
        NSLog(@"not italic");
    }
    [self setNeedsDisplay:YES];
}

- (BOOL)isItalic {
    return isItalic;
}

In prepareAttributes i set the BOOLs to be NO:

- (void)prepareAttributes {
    NSShadow *shadow = [[NSShadow alloc] init];
    [shadow setShadowOffset:NSMakeSize(2.0, 2.0)];
    [shadow setShadowBlurRadius:5.0];
    [shadow setShadowColor:[NSColor blackColor]];
    
    attributes = [NSMutableDictionary dictionary];
    
    [attributes setObject:[NSFont userFontOfSize:75] forKey:NSFontAttributeName];
    
    [attributes setObject:[NSColor redColor] forKey:NSForegroundColorAttributeName];
    
    [attributes setObject:shadow forKey:NSShadowAttributeName];
    
    [self setIsBold:NO];
    [self setIsItalic:NO];
}

When i check or uncheck the checkboxes, i can see that this works (by NSLog), but the letter in the view does not is bold or italic. What am i doing wrong?


#2

You went about it in a rather long winded fashion.

Rather han manually setting the attribs in ‘setbold and setitalics’ do it all at the prepare attributes stage which is called with setNeedsDisplay:YES regardless.

I did it this way:

[code]
-(IBAction)boldClicked:(id)sender{
fontBold = ([sender state] == NSOnState);
[self prepareAttributes];
[self setNeedsDisplay:YES];
}

-(IBAction)italicsClicked:(id)sender{
fontItalic = ([sender state] == NSOnState);
[self prepareAttributes];
[self setNeedsDisplay:YES];
}[/code]

where fontBold and fontItalic are declared in the /h as BOOL’s. In the prepare attribs I check for the state of those variables and set the attribs accordingly:

[code]
-(void)prepareAttributes{
attributes = [[NSMutableDictionary alloc] init];
NSFont font = [NSFont userFontOfSize:75];
NSFontManager fontManager = [NSFontManager sharedFontManager];
//
********** START SET BOLD AND ITALICS BASED ON BOOL VARIABLES
if (fontBold){
font = [fontManager convertFont:font toHaveTrait:NSFontBoldTrait];
}

if (fontItalic){
    font = [fontManager convertFont:font toHaveTrait:NSFontItalicTrait];
}

//************ END SET BOLD AND ITALICS BASED ON BOOL VARIABLES

[attributes setObject:font forKey:NSFontAttributeName];

[attributes setObject:[NSColor redColor] forKey:NSForegroundColorAttributeName];


NSShadow *stringShadow = [[NSShadow alloc] init];
[stringShadow setShadowColor:[NSColor greenColor]];
[stringShadow setShadowBlurRadius:10.0];
[stringShadow setShadowOffset:NSMakeSize(10, 10)];

[attributes setObject:stringShadow forKey:NSShadowAttributeName];

}[/code]

Hope this helps :slight_smile: