不为上下文菜单调用NSMenuDelegate方法 [英] NSMenuDelegate methods not called for contextual menu

查看:110
本文介绍了不为上下文菜单调用NSMenuDelegate方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于文档的应用程序.我想添加一个上下文菜单,当用户右键单击NSTextView中的选定文本时,该菜单显示上下文相关信息.

I have a Document based application. I want to add a contextual menu that displays context-sensitive info when the user right-clicks selected text in an NSTextView.

我已遵循

  • 在我的XIB文件中添加了一个NSMenu作为根对象.
  • 将NSMenu实例连接到NSTextView的menu出口.
  • 将IBAction连接到NSMenu内的NSMenuItem.
    • Added an NSMenu as a root object in my XIB file.
    • Connected the NSMenu instance to the menu outlet of the NSTextView.
    • Connected an IBAction to the NSMenuItem inside the NSMenu.

    到目前为止,一切都很好.一切都按预期进行:菜单项出现,并且在选择操作时将调用该操作.

    So far so good. Every thing works as expected: the menu item appears and the action is called when it is selected.

    在菜单出现之前,我需要从NSTextView获取选定的文本,以便我可以适当地配置菜单项.根据文档

    I need to get the selected text from the NSTextView before the menu appears so that I can configure my menu item appropriately. According to the docs

    如果您需要自定义上下文菜单,可以通过设置 一个适当的对象作为菜单的委托,并实现 menuWillOpen:自定义菜单的方法 出现.

    If you need to customize the contextual menu, you can do so by setting an appropriate object as the menu’s delegate and implementing the menuWillOpen: method to customize the menu as you see fit just before it appears.

    我将NSMenu的委托连接到文件的所有者.没有调用任何委托方法. (menuWillOpen:是我唯一需要的一个,但是我也尝试过其他的).

    I connect the delegate of the NSMenu to File's Owner. None of the delegate methods are called. ( menuWillOpen: is the only one I need, but I've tried others, too).

    我设置IBAction为内部的断点选择菜单项时调用.如果我使用调试器检查菜单,则可以看到委托已正确设置为实现委托方法的对象.

    I set a breakpoint inside the IBAction that gets called when the menu item is selected. If I inspect the menu with the debugger I can see that the delegate is correctly set to the object that implements the delegate method.

    还有其他需要检查的内容吗?我在做任何公然的错误?

    Is there anything else to check? Anything I'm doing blatantly wrong?

    Xcode v4.6.3
    SDK v10.8
    部署目标10.7

    Xcode v4.6.3
    SDK v10.8
    Deployment target 10.7

    推荐答案

    经过一番挖掘,我发现:NSTextView构建一个不同的NSMenu实例以用作上下文菜单,可能是通过覆盖-menuForEvent:或一些类似的内部方法.此新菜单会从您在Interface Builder中创建的菜单中复制菜单项(实际上,它会创建其属性是从原始菜单项复制来的新菜单项实例),但不会复制菜单委托,这就是您的菜单委托的原因没有收到-menuWillOpen:.我不确定这是否是故意的.阅读您发布的文档引用,似乎是一个错误.

    After some digging, this is what I found: NSTextView builds a different NSMenu instance to use as the contextual menu, probably by overriding -menuForEvent: or some similar internal method. This new menu copies the menu items from the menu you created in Interface Builder (in fact, it creates new menu item instances whose attributes are copied from the original menu items) but it does not copy the menu delegate, which is why your menu delegate does not receive -menuWillOpen:. I am not sure whether this is intentional or not. Reading that documentation quote you posted, it seems to be a bug.

    您可以做的是将NSTextView实例的委托设置为一个类符合NSTextViewDelegate的对象(也许是您的文件所有者,它已经符合NSMenuDelegate)并实现以下方法: >

    What you can do is to set the delegate of your NSTextView instance to an object whose class conforms to NSTextViewDelegate (maybe your File’s Owner, which already conforms to NSMenuDelegate) and implement the following method:

    - (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)event atIndex:(NSUInteger)charIndex
    {
        // if the menu delegate is not self, set another object
        [menu setDelegate:self];
    
        return menu;
    }
    

    这将确保由文本视图创建的上下文菜单使用您的委托.

    This will make sure that the contextual menu created by the text view uses your delegate.

    注意:由于NSTextView创建了一个不同的上下文菜单,因此可能是可能要将菜单委托设置为其自身或其他内部对象的情况.在我的测试中,委托为nil,因此看起来很安全.另外,您可以放弃建议的menu参数,并返回正确设置了委托的自己的NSMenu实例.

    NB: since NSTextView creates a different contextual menu, it could be the case that it might want to set the menu delegate to itself or some other internal object. In my tests the delegate is nil, so it looks like it’s safe. Alternatively, you could discard the proposed menu argument and return your own NSMenu instance with the delegate correctly set.

    这篇关于不为上下文菜单调用NSMenuDelegate方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆