4

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?

cacau
  • 3,606
  • 3
  • 21
  • 42
Mojo66
  • 1,109
  • 12
  • 21

2 Answers2

2

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;
}
bvogelzang
  • 1,405
  • 14
  • 17
  • Thanks, but I forgot to mention that the `NSTableView` is view-based. How'd I proceed? – Mojo66 Jun 30 '14 at 20:53
  • @Mojo66 Then you need to set the font for individual labels in the custom cells in `tableView:objectValueForTableColumn:row:` – GoodSp33d Jul 01 '14 at 05:06
  • 1
    I got it working by using `tableView:viewForTableColumn:row:`. Any thoughts about which approach would be more suitable? – Mojo66 Jul 01 '14 at 08:54
1

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.

Mojo66
  • 1,109
  • 12
  • 21