简体   繁体   中英

Change the font, font color and background color of an NSTableView at runtime using NSFontPanel?

I'd like to enable the user to change the font of an view-based NSTableView . I'm using Cocoa bindings and Core Data. In my test code, I do have a changeFont: method that does get called as soon as I press a font-related key combination, like cmd-I or cmd-B , but I've had no luck so far in changing the actual font of the table view:

- (void)changeFont:(id)sender
{
    NSFont *oldFont = [self.airportTableView font];
    NSFont *newFont = [sender convertFont:oldFont];
    NSLog(@"sender: %@ oldfont: %@, newFont: %@ fontmanager selected: %@, font panel selected: %@",
             sender, oldFont, newFont, [sender selectedFont], [sender convertFont:[sender selectedFont]]);
    [self.airportTableView setFont:newFont];
}

produces the following output:

sender: <NSFontManager: 0x6080000b4580> oldfont: (null), newFont: (null) fontmanager selected: (null), font panel selected: (null)

Even this trivial code:

font = [NSFont boldSystemFontOfSize:12];
[self.airportTableView setFont:font];
NSFont *oldFont = [self.airportTableView font];
NSLog(@"oldfont: %@",oldFont);

only results in:

oldfont: (null)

Can any kind soul provide some code that allows the user to change the font of an NSTableView?

You have to set the font of the cell. Not the tableview. Use the following delegate method:

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSTextFieldCell *cell = [tableColumn dataCell];
    [cell setFont:[NSFont systemFontOfSize:11]];
    [cell setTextColor: [NSColor lightGrayColor]];

    return cell;
}

Using the power of the internets, I was able to put together the following code fragment which responds to the NSFontPanel actions for changing font type, font color and background color of an NSTableView :

@interface AppDelegate
{
    NSFont                  *_font;
    NSColor                 *_fontColor;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [[NSFontManager sharedFontManager] setTarget:self];
    _font      = [NSFont systemFontOfSize:0];
    _fontColor = [NSColor blackColor];
}


- (void)changeFont:(id)sender
{
    _font = [sender convertFont:_font];
    [self.airportTableView reloadData];
}

- (void)setColor:(NSColor *)col forAttribute:(NSString *)attr {
    if ([attr isEqualToString:@"NSDocumentBackgroundColor"]) {
        self.airportTableView.backgroundColor = col;
    } else if ([attr isEqualToString:@"NSColor"]) {
        _fontColor  = col;
        [self.airportTableView reloadData];
    }
}


- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

    NSTableCellView *cellView   = [tableView makeViewWithIdentifier:[tableColumn identifier] owner:self];
    NSTextField *textField      = [cellView textField];
    textField.font          = _font;
    textField.textColor     = _fontColor;
    return cellView;
}

- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
    return _font.boundingRectForFont.size.height + 2.0f;
}

Note the explicit calls to reloadData , otherwise the visible part of the table view won't update. Let me know if there are better solutions.

Also note that -setColor:forAttribute: is undocumented. Apparently, if your class responds to it, -changeAttributes: will not get called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM