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

时间:2017-02-27 14:01:21

标签: objective-c swift macos cocoa nstableview

在视图中的特定单元格上右键单击时,是否有任何方法可以阻止上下文菜单(以及相关选择"响铃"在单元格视图周围)基于NSTableView

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

我显然尝试了所有处理选择更改的委托方法但没有效果,因为selectedRow属性没有变化,只有clickedRow。 所以基本上我正在寻找相当于

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

但是对于点击的行而不是选中的行。

注意:问题与 macOS 上的NSTableView有关,而不是iOS上的UITableView

2 个答案:

答案 0 :(得分:2)

我资助了一种方式来做我想做的事情,虽然看起来有点参与一些应该更简单的事情。所以我欢迎任何更简单的解决方案。

可以通过继承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)
    }
} 

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

答案 1 :(得分:0)

不是继承 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"))
        }
    }

}