7

I'm trying to use an NSFontPanel to allow the user to change an application-wide font setting. It's supposed to work something like this: the user clicks a button, a font panel pops up, they choose a font and a size, and their selection is persisted.

The following code shows the panel:

- (IBAction)showFontMenu:(id)sender {
    NSFontManager *fontManager = [NSFontManager sharedFontManager];
    [fontManager setDelegate:self];

    NSFontPanel *fontPanel = [fontManager fontPanel:YES];
    [fontPanel makeKeyAndOrderFront:sender];
}

The documentation seems to suggest that the changeFont:(id)sender method should be called when the font changes; this isn't happening in my case.

- (void)changeFont:(id)sender {
    // blah
}

Any ideas on what I might be doing wrong?

conmulligan
  • 7,038
  • 6
  • 33
  • 44

5 Answers5

9

include this:

[fontManager setTarget:self];
Christian Specht
  • 35,843
  • 15
  • 128
  • 182
Snow
  • 141
  • 1
  • 4
2

The object you've defined -changeFont: on must the first responder or above it in the responder chain. You haven't specified where you've defined the method, but I assume it's on a controller object that is not in the responder chain.

kperryua
  • 10,524
  • 1
  • 38
  • 24
  • The View Controller's view is actually being loaded into another window; adding changeFont: to the parent's ViewController worked. Thanks for your help. – conmulligan Sep 13 '09 at 13:05
1

NSFontManager's delegate exists primarily to filter the fonts it supplies to the font panel via -fontManager:willIncludeFont:.

As kperryua mentions, -changeFont: is sent up the responder chain. The button that launches the font menu or its enclosing view might be a good place to put a responder for -changeFont:.

You might find the Font Handling guide marginally more useful than the Font Panel guide.

Jeremy W. Sherman
  • 35,901
  • 5
  • 77
  • 111
  • Correct link: [Apple's Font Handling](https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html) – VoodooBoot Jan 21 '21 at 07:56
1

The core problem is this line:

[fontPanel makeKeyAndOrderFront:sender];

By making the font panel the key window, it's got no idea where to send action messages like -changeFont: to.

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
0

Here is my working implementation. Key point is you should make your object as the first responder where you have implemented - (void)changeFont:(id)sender

NSFontManager *fontManager = [NSFontManager sharedFontManager];

NSFontPanel *panel = [fontManager fontPanel:YES];
[[self window] makeFirstResponder:self];

[panel orderFront:self];

Simple changeFont: implementation Reference - Font Handling

-(void) changeFont:(id)sender
{
    //Here sender would be NSFontManager
    NSFont *oldFont = [self font];
    NSFont *newFont = [sender convertFont:oldFont];
    [self setFont:newFont];
}
Omkar
  • 1,108
  • 10
  • 19