8

これがまだ尋ねられていないことに驚いています:

しかし、メニューのNSMenuItemタイトルを変更するにはどうすればよいでしょうか。NSStatusBarユーザーがログインするときに、メニュー項目にログアウトと表示させたい。NSMenuItemラベルなどのように自分を変更するためのアウトレットを作成してみました。

AppDelegate.h

@property (retain) IBOutlet NSMenuItem *loginItem;

AppDelegate.m

[loginItem setTitle:@"Logout"];

しかし、それはうまくいきませんでした。

私ができた唯一のことは、古いものを削除してからNSMenuItem新しいものを追加することでしたが、それは単にそれを一番下に追加するだけでした。これを行う唯一の方法は、すべてのメニュー項目を削除してから再度追加することですか?それは非常に非効率的なようです。

4

2 に答える 2

4

あなたが説明した方法は機能するはずですが、一般に、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アウトレットがコントローラ クラス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

于 2013-01-17T04:51:26.593 に答える
1

メニュー項目を接続する必要はありません。これを試してみてください..

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. 
于 2013-01-17T04:35:00.553 に答える