保存首选项以显示或隐藏NSStatusItem

deh*_*len 3 cocoa objective-c nsstatusitem nsstatusbar

我有一个应用程序,作为一个普通的应用程序运行,但也有一个NSStausItem.我希望实现在偏好设置中设置复选框的功能,当此复选框打开时,应显示状态项,但是当复选框关闭时,状态项应被删除或不可见.

我在论坛中发现有人遇到类似问题:如何使用复选框打开和关闭菜单栏中的状态项?

但是我对这个解决方案的问题是它没有按预期工作.所以我做了这个复选框,一切正常,但是当我第二次打开应用程序时,应用程序无法识别我在第一次运行时所做的选择.这是因为复选框没有绑定到某个BOOL或某个东西,复选框只有一个IBAction,它在运行时删除或添加状态项.

所以我的问题是:如何在首选项中创建一个复选框,允许我选择状态项是否应该显示.


好吧其实我试过以下我复制了帖子我给你链接

在AppDelegate.h中:

 NSStatusItem *item;
NSMenu *menu;
IBOutlet NSButton myStatusItemCheckbox;
Run Code Online (Sandbox Code Playgroud)

然后在Delegate.m中:

- (BOOL)createStatusItem
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];

//Replace NSVariableStatusItemLength with NSSquareStatusItemLength if you
//want the item to be square
item = [bar statusItemWithLength:NSVariableStatusItemLength];

if(!item)
  return NO;

//As noted in the docs, the item must be retained as the receiver does not 
//retain the item, so otherwise will be deallocated
[item retain];

//Set the properties of the item
[item setTitle:@"MenuItem"];
[item setHighlightMode:YES];

//If you want a menu to be shown when the user clicks on the item
[item setMenu:menu]; //Assuming 'menu' is a pointer to an NSMenu instance

return YES;
}


- (void)removeStatusItem
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];
[bar removeStatusItem:item];
[item release];
}


- (IBAction)toggleStatusItem:(id)sender
{
BOOL checked = [sender state];

if(checked) {
  BOOL createItem = [self createStatusItem];
  if(!createItem) {
    //Throw an error
    [sender setState:NO];
  }
}
else
  [self removeStatusItem];
}
Run Code Online (Sandbox Code Playgroud)

然后在IBaction我添加了这个:

[[NSUserDefaults standardUserDefaults] setInteger:[sender state]
                                               forKey:@"MyApp_ShouldShowStatusItem"];
Run Code Online (Sandbox Code Playgroud)

在我的awakefromnib中,我添加了这个:`

NSInteger statusItemState = [[NSUserDefaults standardUserDefaults] integerForKey:@"MyApp_ShouldShowStatusItem"];
 [myStatusItemCheckbox setState:statusItemState];
Run Code Online (Sandbox Code Playgroud)

然后在界面构建器中我创建了一个新的复选框,将其连接到"myStatusItemCheckbox"并添加了一个IBaction,我也点击了绑定检查器并在以下绑定的值中设置:NSUserDefaultController并且如ModelKeyPath我设置:MyApp_ShouldShowStatusItem. 不幸的是,这根本不起作用我做错了?

Jos*_*ell 7

您需要做的是使用User Defaults系统.它使保存和加载首选项变得非常容易.

在按钮的操作中,您将保存其状态:

- (IBAction)toggleStatusItem:(id)sender {

    // Your existing code...

    // A button's state is actually an NSInteger, not a BOOL, but
    // you can save it that way if you prefer
    [[NSUserDefaults standardUserDefaults] setInteger:[sender state]
                                               forKey:@"MyApp_ShouldShowStatusItem"];
}
Run Code Online (Sandbox Code Playgroud)

并在您的应用程序委托(或其他适当的对象)中 awakeFromNib,您将从用户默认值中读取该值:

 NSInteger statusItemState = [[NSUserDefaults standardUserDefaults] integerForKey:@"MyApp_ShouldShowStatusItem"];
 [myStatusItemCheckbox setState:statusItemState];
Run Code Online (Sandbox Code Playgroud)

然后确保removeStatusItem在必要时打电话.

此过程几乎适用于您可能要保存的任何首选项.

  • 您还需要使用该值.控制器不应该保留值并从复选框中检索它,而应该知道状态项是否应该直接位于状态栏中.由于这是一个二元选择,它应该是一个布尔值,控制器应该将它存储在默认值中,并根据布尔值将复选框设置为"NSOnState"或"NSOffState".(`NSOnState`和`YES`恰好被定义为相同的数字,并且对于'NSOffState`和`NO`来说是相同的,但清晰度和显性是美德.) (2认同)