2

我的主菜单项“复制”不可点击:

在此处输入图像描述

但我在 Xcode 中启用它:

在此处输入图像描述

我在代码中没有任何主菜单项的出口。我可以做什么?

4

1 回答 1

9

应用程序菜单和弹出列表编程主题中的“启用菜单项”是这样说的:

默认情况下,每次发生用户事件时,都会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:检查哪个菜单项正在被验证并返回YESNO酌情返回。

例如,应用程序委托位于响应者链中。因此,您可以将此方法添加到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;
}
于 2013-04-05T19:59:06.930 回答