macOS开发中对于鼠标的支持没有Windows那种的鼠标悬停功能,需要自己手动去实现。幸运的是可以检测鼠标在NSView的滑入和退出等事件,我们可以通过这种方式来实现鼠标的监听,开确认是否显示菜单,然后转换为对应的位置,再根据位置后去搜找对应cell,之后添加菜单显示操作即可实现啦?
定义一个protocol
```
@objc protocol ContextMenu {
@objc func tableView(_ tableView: NSTableView, menuForRows rows:IndexSet)->NSMenu?
@objc func tableView(_ tableView: NSTableView, clickForRow row: Int) -> Void
}
```
extension tableview重写鼠标事件
```
extension NSTableView {
open override func menu(for event: NSEvent) -> NSMenu? {
let location = self.convert(event.locationInWindow, from: nil)
let row = self.row(at: location)
if row >= 0 && event.type == .rightMouseDown {
var selected = self.selectedRowIndexes
if false == selected.contains(row) {
selected = IndexSet.init(integer: row)
self.selectRowIndexes(selected, byExtendingSelection: false)
}
if let dele:ContextMenu = (self.delegate as? ContextMenu) {
return dele.tableView(self, menuForRows: selected)
}else{
return super.menu(for: event)
}
}
return super.menu(for: event)
}
open override func mouseDown(with event: NSEvent) {
let location = self.convert(event.locationInWindow, from: nil)
let row = self.row(at: location)
if row >= 0 && event.type == .rightMouseDown {
var selected = self.selectedRowIndexes
if false == selected.contains(row) {
selected = IndexSet.init(integer: row)
self.selectRowIndexes(selected, byExtendingSelection: false)
}
if let dele:ContextMenu = (self.delegate as? ContextMenu) {
dele.tableView(self, clickForRow: row)
}
}
return super.mouseDown(with: event)
}
open override func mouseEntered(with event: NSEvent) {
var btInfo:BTInfo = BTInfo()
}
open override func mouseExited(with event: NSEvent) {
}
}
```
使用
```
extension BTViewController: ContextMenu{
@objc func tableView(_ tableView: NSTableView, menuForRows rows:IndexSet)->NSMenu?{
let bt: BT = self.bts![self.btTableView.selectedRow]
return self.menus(forTables: tableView, item: bt)
}
@objc func tableView(_ tableView: NSTableView, clickForRow row: Int) -> Void {
}
}
```