2013-01-17 16 views
5

林驚訝,這尚未問:如何改變NSMenuItem標題(登錄註銷)

但要如何去約在NSStatusBar菜單改變NSMenuItem稱號。當用戶登錄時,我希望菜單項說出註銷。我試圖創建一個插座來修改我的NSMenuItem作爲一個標籤或什麼的。

AppDelegate.h

@property (retain) IBOutlet NSMenuItem *loginItem;

AppDelegate.m

[loginItem setTitle:@"Logout"];

但沒有工作。

我能做的唯一的事情就是刪除舊的NSMenuItem,然後添加一個新的,但它只是將其添加到底部。是唯一的方法來做到這一點,刪除每個菜單項然後重新添加他們?這似乎非常低效。

+1

有沒有在你的例子,建議你沒有正確地這樣做。但是,你真的把你的IBOutlet連接到菜單項嗎? – trudyscousin

回答

4

你描述應該工作,但是,在一般情況下,保持IBOutlet獻給所有的菜單項的方法可能很乏味。 (如果您的解決方案無法正常工作,請確保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類在響應者鏈中,並允許它與validating the menu items一起使用。

然後,你可以實現你的.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

1

你並不需要連接你的菜單項只是嘗試這個..

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

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

      [menuItem setTitle:@"LogOut"]; 
} 

NSMenuItem 菜單項=(NSMenuItem)發送;

 this line automatically collect the menu items in your app.