Как изменить заголовок NSMenuItem (войти в систему)
Я удивлен, что об этом еще не спрашивали:
Но как можно изменить NSMenuItem
название в NSStatusBar
меню. Когда пользователь входит в систему, я хочу, чтобы пункт меню сказал выход. Я пытался создать выход, чтобы изменить мой NSMenuItem
как бы ярлык или что-то.
AppDelegate.h
@property (retain) IBOutlet NSMenuItem *loginItem;
AppDelegate.m
[loginItem setTitle:@"Logout"];
Но это не сработало.
Единственное, что мне удалось сделать, это удалить старые NSMenuItem
, затем добавьте новый, но он просто добавит его внизу. Это единственный способ сделать это, чтобы удалить все пункты меню, а затем повторно добавить их?? Это кажется очень неэффективным.
2 ответа
Метод, который вы описываете, должен работать, хотя, в целом, сохраняя IBOutlet
s для всех ваших пунктов меню может быть утомительным. (Если ваше решение не работает, убедитесь, что IBOutlet
на самом деле подключен в файл пера, и убедитесь, что вы устанавливаете заголовок в соответствующее время. Если вы пытаетесь установить его в вашем контроллере 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
В файле пера delegate
выход из statusItemMenu
установлен на 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/NSStatusBarFinagler
Вам не нужно подключать свой пункт меню, просто попробуйте это..
NSMenuItem *menuItem = (NSMenuItem*) sender;
NSString *menuString = menuItem.title;
if ([menuString isEqualToString:@"Login"])
{
[menuItem setTitle:@"LogOut"];
}
NSMenuItem menuItem = (NSMenuItem) отправитель;
this line automatically collect the menu items in your app.