【发布时间】:2012-09-19 12:13:52
【问题描述】:
我正在寻找一种从NSTableView 获取右键单击行索引的方法,但我找不到任何委托方法或类属性。任何建议表示赞赏。
【问题讨论】:
标签: objective-c cocoa nstableview
我正在寻找一种从NSTableView 获取右键单击行索引的方法,但我找不到任何委托方法或类属性。任何建议表示赞赏。
【问题讨论】:
标签: objective-c cocoa nstableview
使用NSTableView方法- (NSInteger)clickedRow获取最后点击的行的索引。返回的 NSInteger 将是右击行的索引。
对于此解决方案,您不需要为 NSTableView 子类化。 clickedRow 也可以在 NSOutlineView 上找到。
【讨论】:
menu 插座已设置,如果您覆盖-menuForEvent:,则必须调用super。
虽然我没有这样做,但我很确定您可以通过覆盖 NSView 的 - (NSMenu*)menuForEvent:(NSEvent*)theEvent 来实现。 this link 中的示例进行点转换以确定索引。
-(NSMenu*)menuForEvent:(NSEvent*)theEvent
{
NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
int row = [self rowAtPoint:mousePoint];
// Produce the menu here or perform an action like selection of the row.
}
【讨论】:
如果您想在打开菜单时获得点击的行索引,答案是NSTableView.clickedRow。无论如何,此属性仅在特定时刻可用,通常只是 -1。
该索引何时可用?那是在NSMenuDelegate.menuWillOpen 方法中。因此,您符合委托并在您的类上实现该方法,并访问clickedRow 属性。完成了。
final class FileNavigatorViewController: NSViewController, NSMenuDelegate {
let ov = NSOutlineView() // Assumed you setup this properly.
let ctxm = NSMenu()
override func viewDidLoad() {
super.viewDidLoad()
ov.menu = ctxm
ctxm.delegate = self
}
func menuWillOpen(_ menu: NSMenu) {
print(outlineView.clickedRow)
}
}
在您单击菜单中的项目之前,单击的行索引可用。所以这也有效。
final class FileNavigatorViewController: NSViewController {
let ov = NSOutlineView() // Assumed you setup this properly.
let ctxm = NSMenu()
let item1 = NSMenuItem()
override func viewDidLoad() {
super.viewDidLoad()
ov.menu = ctxm
ov.addItem(item1)
ov.target = self
ov.action = #selector(onClickItem1(_:))
}
@objc
func onClickItem1(_: NSObject?) {
print(outlineView.clickedRow)
}
}
我在 macOS Sierra (10.12.5) 上对此进行了测试。
从 OS X 10.11 开始,Apple 终于添加了一种可以轻松访问clickedRow 的方法。只需继承 NSTableView 并覆盖此方法,就我所经历的而言,您将获得 clickedRow。
func willOpenMenu(menu: NSMenu, withEvent event: NSEvent)
这需要子类化,但无论如何,这是访问clickedRow 的最干净和最简单的方法。
此外,还有一种配对方法。
func didCloseMenu(menu: NSMenu, withEvent event: NSEvent?)
【讨论】:
只需通过在NSTableView 子类中实现menuForEvent: 来右键单击选择行:
@implementation MyTableView
- (NSMenu *)menuForEvent:(NSEvent *)theEvent
{
int row = [self rowAtPoint:[self convertPoint:theEvent.locationInWindow fromView:nil]];
if (row == -1)
return nil;
if (row != self.selectedRow)
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
return self.menu;
}
@end
【讨论】:
如果您不需要打开 NSMenu 但需要知道“带有行号的右键单击操作”,我认为最简单的方法如下。 (Swift4 代码)不需要任何其他连接的外部 NSMenu 类。
class SomeViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var tableView: NSTableView!
...
override func viewDidLoad() {
...
tableView.action = #selector(some method()) // left single click action
tableView.doubleAction = #selector(someMethod()) // left double click action
}
// right click action
override func rightMouseDown(with theEvent: NSEvent) {
let point = tableView.convert(theEvent.locationInWindow, from: nil)
let row = tableView.row(at: point)
print("right click")
print(row)
}
【讨论】: