我的主菜单项“复制”不可点击:
但我在 Xcode 中启用它:
我在代码中没有任何主菜单项的出口。我可以做什么?
应用程序菜单和弹出列表编程主题中的“启用菜单项”是这样说的:
默认情况下,每次发生用户事件时,都会
NSMenu
自动启用和禁用每个可见菜单项。NSMenu
您还可以使用'方法强制更新菜单update
。
还有这个:
如果菜单项的目标未设置(也就是说,如果是——通常
nil
如果菜单项连接到 First Responder)并且NSMenu
对象不是上下文菜单,则NSMenu
使用响应者链(在“响应者链”中描述< /a> in Cocoa Event Handling Guide ) 来确定目标。如果响应者链中没有实现该项目操作的对象,则该项目被禁用。如果响应者链中有一个对象实现了该项目的操作,NSMenu
则检查该对象是否实现了validateMenuItem:
orvalidateUserInterfaceItem:
方法。如果没有,则启用菜单项。如果是,则菜单项的启用状态由方法的返回值确定。
默认情况下(当您使用“Cocoa Application”模板创建项目时),复制菜单项的目标是 First Responder ( nil
),动作是copy:
. 因此,您需要copy:
在响应者链中的某些项目上实现该方法。这足以启用菜单项。如果您想更精确地控制何时启用菜单项,您还可以实现validateMenuItem:
检查哪个菜单项正在被验证并返回YES
或NO
酌情返回。
例如,应用程序委托位于响应者链中。因此,您可以将此方法添加到CMAppDelegate
:
- (IBAction)copy:(id)sender {
NSLog(@"%@ %s", self, __func__);
}
这应该足以启用“复制”菜单项。当然,选择 Edit > Copy 只会将消息记录到控制台。由您实际编写复制用户选择的任何内容的代码。
如果您想要更精细的控制,请尝试为应用委托提供连接到 Copy 菜单项的插座:
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (strong) IBOutlet NSMenuItem *copyMenuItem;
@end
将插座连接在MainMenu.xib
. 然后你可以validateMenuItem:
这样实现:
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
if (menuItem == self.copyMenuItem) {
NSLog(@"%@ %s %@", self, __func__, menuItem);
return [self shouldEnableCopyMenuItem];
}
return NO;
}