NSCollectionView 不弹出上下文菜单?

NSCollectionView doesn't popup context menu?

我已将菜单绑定到界面生成器中的 NSCollectionView。但是当我按住 CTRL 并单击(右键单击)时,菜单没有显示。

我试过向 NSCollectionView 子类添加一些方法。 None 个被调用:

+ (NSMenu*)defaultMenu
- (NSMenu *)menuForEvent:(NSEvent *)theEvent
- (void)rightMouseDown:(NSEvent *)theEvent
- (void)sendEvent:(NSEvent *)theEvent

唯一调用的方法是:

- (NSView *)hitTest:(NSPoint)aPoint

也就是说NSCollectionView接收到了鼠标事件

我也试过在NSCollectionViewItem的子类中添加同样的方法,结果是一样的。仅调用 hitTest:

这对我有用:

@interface MyCollectionView : NSView
-(void)mouseDown:(NSEvent *)theEvent;
@end

@implementation MyCollectionView

-(void)mouseDown:(NSEvent *)theEvent
{

    NSMenu *theMenu = [[NSMenu alloc] initWithTitle:@"Contextual Menu"];
    [theMenu insertItemWithTitle:@"Beep" action:@selector(beep) keyEquivalent:@"" atIndex:0];
    [theMenu insertItemWithTitle:@"Honk" action:@selector(honk) keyEquivalent:@"" atIndex:1];

    [NSMenu popUpContextMenu:theMenu withEvent:theEvent forView:self];

    [super mouseDown:theEvent];

}

-(void)beep{

}

-(void)honk{

}

@end

希望对您有所帮助。

我对 "new" NSCollectionView 也有同样的问题。上下文菜单是在 xib 中设置的,它实际上是由鼠标右键单击以及触控板上的双指选项卡正确触发的(如果用户在系统偏好设置中设置了该选项),但不是通过控制点击。因此,这似乎是 NSCollectionView 的合法错误或限制,可能取决于它的设置方式。

无论如何,这是一个较短的解决方案,Swift 中的这个解决方案假设您已经使用集合视图的 menu 插座设置了上下文菜单(或者您有它的设置如 Apple's documentation) 中所述。

您需要创建 NSCollectionView 的子类,并在 xib 中为集合视图选择子类。这是子类的代码:

import Cocoa

class MyCollectionView: NSCollectionView {

    /// Fixes the behavior of collection view with control-click, that does not properly trigger the contextual menu.
    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)
        if event.type == .rightMouseDown || event.modifierFlags.contains(.control) {
            rightMouseDown(with: event)
        }
    }

}

NSCollectionView 的子类

class OSCollectionView: NSCollectionView {

    
    override func menu(for event: NSEvent) -> NSMenu? {
        print("menu() called")
        let menu = NSMenu()
        menu.addItem(NSMenuItem(title: "Create a clone", action: #selector(clone(_:)), keyEquivalent: ""))
        return menu
    }
    
    
    @objc
    func clone(_ sender: Any){
        //editDelegate?.terminateAndReplace(self)
        print("Clone item")
    }
}