使用动作选择器预设将项目添加到 NSMenu
Posted
技术标签:
【中文标题】使用动作选择器预设将项目添加到 NSMenu【英文标题】:Adding item to NSMenu with action selector preset 【发布时间】:2010-12-30 12:28:16 【问题描述】:我是 Obj-C/Cocoa 编程的新手,我在尝试将菜单项动态添加到 NSMenu 实例并在插入时已设置项操作选择器时遇到问题。
我可以,添加动态菜单项很好,但是当通过菜单单击该项目时,操作选择器不会触发。
下面的第一行是我用来添加菜单项的代码行。您可以将我正在设置操作:(SEL)aSelector 设置为“openEchowavesURL”函数。
这个函数在同一个控制器类文件中,我在下面包含了函数定义。
我只是调用了错误的选择器语法或其他东西吗?或者让菜单项在单击时调用选择器的技巧是什么?
[statusMenu insertItemWithTitle:[NSString stringWithFormat:@"%d - %@", convo.newMessagesCount, convo.ewName] action:@selector(openEchowavesURL:) keyEquivalent:@"" atIndex:0];
- (void)openEchowavesURL:(id)sender
// function details here
【问题讨论】:
【参考方案1】:如果您希望针对您的对象触发操作,您必须为新的NSMenuItem 指定一个目标:
NSMenuItem *item = [statusMenu insertItemWithTitle:[NSString stringWithFormat:@"%d - %@", convo.newMessagesCount, convo.ewName] action:@selector(openEchowavesURL:) keyEquivalent:@"" atIndex:0];
[item setTarget:self]; // or whatever target you want
如果你不这样做,那么NSResponder 链将被遍历,直到一个对象响应选择器。
【讨论】:
谢谢。那么,如果链是走的,那么为什么在我当前的控制器类中找不到选择器?为什么在这种情况下我需要手动指定 self? 您必须满足特定条件才能在搜索过程中被查询。我建议您阅读以下指南以了解如何操作:developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/… 您的控制器可能不是响应者链的一部分。 类通常不是控制目标。响应者是实例。您的对象可能会响应选择器,但如果它不在响应者链中并且您没有将控件的目标专门设置为您的对象,那么消息将永远不会到达您的对象。解决方案是让您的对象成为响应者并将其保留在响应者链中,或者将控件的目标设置为您的对象。【参考方案2】:动作需要一个目标,否则它们会被发送到 nil,然后应用新规则。
【讨论】:
你能再解释一下吗?我不认为我跟随。我在插入的菜单项上将操作设置为我想要的选择器。关于设定目标,我还需要做什么? 向项目发送 setTarget 消息。 如果您将操作发送到 nil (NULL),那么将使用 firstResponder(尽可能)。在排序中:要让最前面的窗口处理操作,请将目标设置为 NULL。在 Interface Builder 中,您将操作添加到 FirstResponder 类,然后将操作直接连接到 firstResponder 实例而不是您自己的对象。 - 通常将目标设置为 NULL 是一个好主意(尤其是对于菜单项)。请记住,您还可以使用representedObject
来保存对数据/对象的引用。以上是关于使用动作选择器预设将项目添加到 NSMenu的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3使用选择器将按钮/手势识别器动作传递给其他功能