NSMenuItem 的值与 BOOL 绑定

发布于 2024-08-21 06:02:29 字数 932 浏览 1 评论 0原文

我在将 NSMenuItem 的“值”绑定到 BOOL 时遇到一些问题。

我将问题简化为:

1)菜单项必须调用更改 BOOL 值的操作方法,否则它将不起作用(即,如果 NSButton 调用更改 BOOL 值的方法) BOOL 则菜单项不会更新)

2) 即使操作方法使 BOOL 为常量(即 enabled = YES),菜单项的“值”仍然会交替。

有什么想法吗?我很困惑!

下面是代码:

MenuBindings_AppDelegate.h

#import <Cocoa/Cocoa.h>

@interface Menu_BindingsAppDelegate : NSObject <NSApplicationDelegate> 
{   
   BOOL foo;
}

- (IBAction)toggle:(id)sender;
- (IBAction)makeYes:(id)sender;

@property BOOL foo;

@end

Menu_BindingsAppDelegate.m

@implementation Menu_BindingsAppDelegate

@synthesize foo;

- (IBAction)toggle:(id)sender
{
   [self setFoo:!foo];
}

- (IBAction)makeYes:(id)sender
{   
   [self setFoo:YES];
}

@end

在我的笔尖中,我有一个连接到 -makeYes: 操作的按钮和一个连接到 -toggle 的菜单项:行动。菜单项的“value”绑定绑定到应用程序委托的“foo”属性。

谢谢。

I am having some issues binding an NSMenuItem's "value" binding to a BOOL.

I simplified the problem to this:

1) The menu item must call the action method that changes the value of the BOOL otherwise it doesn't work (i.e. if an NSButton calls a method that changes the value of the BOOL then the menu item won't update)

2) Even if the action method makes the BOOL a constant (i.e. enabled = YES), the "value" of the menu item still alternates.

Any ideas? I'm so confused!

Here is the code:

MenuBindings_AppDelegate.h

#import <Cocoa/Cocoa.h>

@interface Menu_BindingsAppDelegate : NSObject <NSApplicationDelegate> 
{   
   BOOL foo;
}

- (IBAction)toggle:(id)sender;
- (IBAction)makeYes:(id)sender;

@property BOOL foo;

@end

Menu_BindingsAppDelegate.m

@implementation Menu_BindingsAppDelegate

@synthesize foo;

- (IBAction)toggle:(id)sender
{
   [self setFoo:!foo];
}

- (IBAction)makeYes:(id)sender
{   
   [self setFoo:YES];
}

@end

In my nib, I have a button connected to the -makeYes: action and a menu item connected to the -toggle: action. The menu item's "value" binding is bound to the app delegate's "foo" attribute.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏日落 2024-08-28 06:02:29

Cocoa Bindings 使用键值观察 (KVO) 获取模型对象更改的通知。为了让观察者(包括任何使用绑定的视图)注意到模型的更改(您的 BOOL 值),您必须使用键值编码兼容的访问器方法。如果您直接设置 ivar 的值,则不会发送 KVO 通知。

您可以自己实现 KVC 访问器,也可以声明一个属性并在实现中使用 @synthesize 关键字,让编译器为您创建兼容的访问器。

这是实现符合 KVC 的访问器的方式:

//YourModel.h
@interface YourModel : NSObject
{
    BOOL enabled;
}
- (BOOL)enabled;
- (void)setEnabled:(BOOL)flag;
@end

//YourModel.m
@implementation YourModel
- (BOOL)enabled
{
    return enabled;
}
- (void)setEnabled:(BOOL)flag
{
    enabled = flag;
}
@end

这也是使用 Objective-C 2.0 属性语法执行相同操作的方式:

//YourModel.h
@interface YourModel : NSObject
{
    BOOL enabled;
}
@property BOOL enabled;
@end

//YourModel.m
@implementation YourModel
@synthesize enabled;
@end

然后您可以调用 [yourModel setEnabled:YES] 和任何已注册的 KVO观察者(包括您的菜单绑定)将被告知更改。

或者,您可以调用 yourModel.enabled = YES ,它将使用正确的 KVC 访问器(如果可用)。

我上传了一个示例项目来演示它是如何完成的。

Cocoa Bindings uses Key-Value Observing (KVO) to obtain notification of changes in model objects. In order for the change in the model (your BOOL value) to be noticed by observers including any views that use bindings, you must update the model using Key-Value Coding-compliant accessor methods. If you just set the value of the ivar directly, no KVO notifications will be sent.

You can either implement the KVC accessors yourself or declare a property and use the @synthesize keyword in your implementation to have the compiler create compliant accessors for you.

This is how you would implement KVC-compliant accessors:

//YourModel.h
@interface YourModel : NSObject
{
    BOOL enabled;
}
- (BOOL)enabled;
- (void)setEnabled:(BOOL)flag;
@end

//YourModel.m
@implementation YourModel
- (BOOL)enabled
{
    return enabled;
}
- (void)setEnabled:(BOOL)flag
{
    enabled = flag;
}
@end

and this is how you would do the same thing using Objective-C 2.0 property syntax:

//YourModel.h
@interface YourModel : NSObject
{
    BOOL enabled;
}
@property BOOL enabled;
@end

//YourModel.m
@implementation YourModel
@synthesize enabled;
@end

You can then call [yourModel setEnabled:YES] and any registered KVO observers (including your menu binding) will be informed of the change.

Alternatively, you can call yourModel.enabled = YES which will use the proper KVC accessors if available.

I uploaded a sample project to demonstrate how it's done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文