防止在基于 NSTableView 的视图中的特定单元格上显示上下文菜单

Preventing contextual menu showing on specific cell in a view based NSTableView

有什么方法可以防止在 右键单击 中的特定单元格时显示上下文菜单(以及单元格视图周围的相关选择 "ring")基于视图 NSTableView ?

我不是在谈论禁用对所有单元格的右键单击操作,而是仅针对特定单元格。

我显然已经尝试了所有处理选择更改的委托方法,但 none 有效,因为 selectedRow 属性 没有更改,只有 clickedRow 会更改。 所以基本上我在寻找等同于

的东西
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool 

但是 clicked 行不是 selected 行。

注意:问题是关于 macOS 上的 NSTableView 而不是 [=37 上的 UITableView =].

我已经找到了一种方法来做我想做的事情,尽管看起来应该更简单一些。所以我欢迎任何更简单的解决方案。

可以通过子类化 NSTableView 来完成:

class MyTableView : NSTableView {

    override func menu(for event: NSEvent) -> NSMenu? {
        let clickedPoint = self.convert(event.locationInWindow, from: nil)
        let row = self.row(at: clickedPoint)

        // no contextual menu for the last row
        return row == self.numberOfRows - 1 ? nil : super.menu(for: event)
    }
} 

此示例阻止在最后一行显示上下文菜单,但可以通过向每个单元格的菜单添加一个带有方法的委托来实现更通用的解决方案。return

不是子类化 NSTableView,更简单的方法是设置菜单委托并删除 public func menuNeedsUpdate(_ menu: NSMenu) 委托方法中的所有项目。

示例:

class MyViewController: NSViewController  {

    override func viewDidLoad() {
        let menu = NSMenu()
        menu.delegate = self

        tableView.menu = menu
    }

}


extension MyViewController: NSMenuDelegate  {

    public func menuNeedsUpdate(_ menu: NSMenu) {
        //This will prevent menu from showing
        menu.removeAllItems()

        //Check if user has clicked on the cell or somewhere inside tableView 
        //area that is not populated with cells
        guard tableView.clickedRow >= 0 else { return }

        //Get model
        let item = items[tableView.clickedRow]

        //For cells that need context menu, add necessary menu items
        if item.needsContextMenu {
            menu.addItem(NSMenuItem(title: "Edit", action: #selector(tableViewEditItemClicked(_:)), keyEquivalent: "e"))
            menu.addItem(NSMenuItem(title: "Delete", action: #selector(tableViewEditItemClicked(_:)), keyEquivalent: "d"))
        }
    }

}