urb*_*der 5 cocoa objective-c nsmenuitem
我很惊讶,这还没有被问到:
但是如何改变菜单中的NSMenuItem标题呢NSStatusBar?当用户登录时,我希望菜单项说出注销.我试过创建一个插座来修改我NSMenuItem的标签或其他东西.
AppDelegate.h
@property (retain) IBOutlet NSMenuItem *loginItem;
AppDelegate.m
[loginItem setTitle:@"Logout"];
但那没有用.
我唯一能做的就是删除旧的NSMenuItem,然后添加一个新的,但它只是将它添加到底部.是唯一的方法来删除每个菜单项然后重新添加它们?这似乎非常低效.
您描述的方法应该有效,但一般来说,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
Run Code Online (Sandbox Code Playgroud)
在nib文件中,delegateoutletstatusItemMenu被设置为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;
}
Run Code Online (Sandbox Code Playgroud)
示例项目:http://github.com/NSGod/NSStatusBarFinagler