您描述的方法应该可以工作,但是,一般来说,IBOutlet
为所有菜单项保留 s 可能很乏味。(如果您的解决方案不起作用,请确保IBOutlet
在 nib 文件中实际连接,并确保您在适当的时间设置标题。如果您尝试在控制器的init
方法中设置它,例如,现在还为时过早,并且插座尚未连接:将方法移至awakeFromNib
或类似。
从长远来看,更好的方法是使用<NSMenuDelegate>
协议和NSMenuValidation
(非正式)协议来动态(和懒惰地)更新菜单项。
例如,定义您的控制器类,如下所示:
@interface MDAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>
@property (strong) NSStatusItem *statusItem;
@property (weak) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSMenu *statusItemMenu;
@property (weak) IBOutlet NSMenuItem *toggleLoginLogoutMenuItem;
@property (weak) IBOutlet NSTextField *statusField;
@property (weak) IBOutlet NSTextField *progressField;
@property (weak) IBOutlet NSProgressIndicator *progressIndicator;
@property (assign) BOOL loggedIn;
- (IBAction)toggleLoginLogout:(id)sender;
@end
在 nib 文件中,delegate
outletstatusItemMenu
设置为MDAppDelegate
控制器类。这确保了MDAppDelegate
类在响应者链中并允许它与验证菜单项一起工作。
然后你可以像下面这样实现你的 .m :
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
_statusItem.menu = _statusItemMenu;
_statusItem.title = NSLocalizedString(@"NSStatusItem", @"");
[self updateLoggedInStatus];
}
- (void)updateLoggedInStatus {
[self.statusField setStringValue:(self.loggedIn ? @"Logged in" : @"Logged out")];
}
- (IBAction)toggleLoginLogout:(id)sender {
[self performSelector:@selector(finishFakeLoginLogout:)
withObject:nil afterDelay:2.0];
}
- (void)finishFakeLoginLogout:(id)sender {
self.loggedIn = !self.loggedIn;
[self updateLoggedInStatus];
}
- (void)menuNeedsUpdate:(NSMenu *)menu {
#if MD_DEBUG
NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
#endif
}
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
#if MD_DEBUG
NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
#endif
SEL action = menuItem.action;
if (action == @selector(toggleLoginLogout:)) {
[menuItem setTitle:(self.loggedIn ? @"Logout" :@"Login")];
}
return YES;
}
示例项目:http: //github.com/NSGod/NSStatusBarFiagler