Pergunta

My code is split into two main implementations: MenuController.m and AppController.m, each with header files.

I have a couple user preferences, which are stored using NSUserDefaults, and changed via NSMenuItems so that they show check marks when enabled (using setState: NSOffState). There's only one missing bit of my setup- I need the app to setState for those menu items on startup if the options are on in the prefs. However, the only way I know to set something on app launch is to have it in the awakeFromNib method, and that's in the AppController and can't access the NSMenuItem instantiated in the MenuController.

I am rather new to Objective-C, and have managed to get this far thanks to many helpful tutorials and answers on this site, but right now I'm just stumped.

I've tried using class and object methods to change the settings, but have failed- I need to use the existing instance of the NSMenuItems. validateMenuItem looked promising, but it only enables and disables menus and doesn't setState.

Relevant code (I think):

from MenuController.h:

@interface MenuController : NSMenu {
 IBOutlet NSMenu *optionsMenu;
 IBOutlet NSMenuItem *onTopItem;
 IBOutlet NSMenuItem *liveIconItem;
}

- (IBAction)menuLiveIconToggle:(id)pid;

from MenuController.m: (method to change prefs and setState- works great)

- (IBAction)menuLiveIconToggle:(id)pid; {
 //NSLog(@"Live Icon Toggle");
 NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
 if ([standardUserDefaults boolForKey:@"LiveIcon"] == TRUE){
  [standardUserDefaults setBool:FALSE forKey:@"LiveIcon"];
  [liveIconItem setState: NSOffState];
 } else {
  [standardUserDefaults setBool:TRUE forKey:@"LiveIcon"];
  [liveIconItem setState: NSOnState];
 }
 [standardUserDefaults synchronize];
}

from AppController.m: (does NOT work, but this is the gist of it)

- (void) awakeFromNib{
 // Update menu items
 if ([standardUserDefaults boolForKey:@"LiveIcon"] == TRUE) {
  [liveIconItem setState: NSOnState];
 } else {
  [liveIconItem setState: NSOffState];
 }
}

Thanks for any help!

Foi útil?

Solução

There are several ways you could achieve this. First, you could simply move your awakeFromNib implementation into your MenuController class, where you have access to the outlets. awakeFromNib is not specific to the App Delegate, but available for all objects that are loaded from Nibs (as you have outlets in your MenuController, I assume that it is loaded from a Nib).

You could also implement validateMenuItem:, always return YES, but also set the state of the menu item that is given to you as the parameter.

Or, get rid of all the code and just use bindings in Interface Builder. You can bind the "value" (== state) of your menu item to the "Shared User Defaults Controller" and enter "LiveIcon" as the model key path. You can then delete all of the code you posted and it'll just work.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top