2013-01-17 9 views
5

Im zaskoczony, że nie zostało już zadane:Jak zmienić NSMenuItem tytułowy (Zaloguj się Wyloguj)

Ale w jaki sposób można przejść o zmianę tytułu NSMenuItem w menu NSStatusBar. Gdy użytkownik się loguje Chcę, aby pozycja menu mówiła wylogowanie. Próbowałem stworzyć gniazdo do modyfikacji mojego NSMenuItem jako etykiety lub czegoś.

AppDelegate.h

@property (retain) IBOutlet NSMenuItem *loginItem;

AppDelegate.m

[loginItem setTitle:@"Logout"];

Ale to nie działał.

Jedyne, co udało mi się zrobić, to usunąć starego NSMenuItem, a następnie dodać nowy, ale wystarczy dodać go na samym dole. Czy jest to jedyny sposób, aby usunąć wszystkie pozycje menu, a następnie ponownie je dodać? Wydaje się to bardzo nieefektywne.

+1

Nie ma nic w swojej przykład sugerować, że robisz to nieprawidłowo. Ale czy naprawdę podłączyłeś swój "IBOutlet" do pozycji menu? – trudyscousin

Odpowiedz

4

opisać powinny działać, choć w ogóle, utrzymując IBOutlet s dla wszystkich elementów menu metoda może być uciążliwe. (Jeśli twoje rozwiązanie nie działa, upewnij się, że IBOutlet jest rzeczywiście podłączony do pliku nib, i upewnij się, że ustawiasz tytuł w odpowiednim czasie. Jeśli próbujesz ustawić go w kontrolerze init sposób, na przykład, że jest zbyt wcześnie, i wyloty nie zostały jeszcze podłączone: przenieść metodę awakeFromNib lub podobny

lepszym rozwiązaniem na dłuższą metę jest użycie protokołu <NSMenuDelegate> i NSMenuValidation (nieformalny.), aby dynamicznie (i leniwie) aktualizować elementy menu:

Na przykład zdefiniuj swoją klasę kontrolera, tak jak poniżej:

@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 

W pliku nib, wylot statusItemMenudelegate jest ustawiona do klasy MDAppDelegate kontrolera. Zapewnia to, że klasa MDAppDelegate znajduje się w łańcuchu respondentów i umożliwia jej pracę z validating the menu items.

Następnie można zaimplementować .m jak następuje:

- (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; 
} 

przykładowy projekt: http://github.com/NSGod/NSStatusBarFinagler

1

Nie trzeba podłączyć menu po prostu spróbować tego ..

NSMenuItem *menuItem = (NSMenuItem*) sender; 
    NSString *menuString = menuItem.title; 

    if ([menuString isEqualToString:@"Login"]) 
{ 

      [menuItem setTitle:@"LogOut"]; 
} 

NSMenuItem MENUITEM = (NSMenuItem) nadawca;

 this line automatically collect the menu items in your app.