我正在寻找一种优雅的方法来检测 NSTableView 表头上的右键单击/ctrl+单击。
当发生右键单击时,我希望显示一个上下文菜单。
- (NSMenu *)menuForEvent:(NSEvent *)
在表格中仅检测右键单击事件,而不是在表头中检测。
感谢您的帮助。
我正在寻找一种优雅的方法来检测 NSTableView 表头上的右键单击/ctrl+单击。
当发生右键单击时,我希望显示一个上下文菜单。
- (NSMenu *)menuForEvent:(NSEvent *)
在表格中仅检测右键单击事件,而不是在表头中检测。
感谢您的帮助。
在任何tableView上,您可以选择TableView并将菜单outlet连接到菜单。
现在,您可以将菜单的选择器(右侧)与您的代码连接起来。
[yourTableView clickedRow]
完成。像老板一样。
从NSTableView获取NSTableHeaderView并设置其菜单。
[[myTableView headerView] setMenu:aMenu];
NSTableHeaderView
的子类。虽然在不创建子类的情况下弹出菜单是可能的,但是找不到哪个表列被点击了,这就使得上下文菜单变得无用。NSTableHeaderView
,将其分配给您的自定义子类,并连接它的新delegate
输出口。此外,创建一个菜单并将其分配给menu
输出口。-validateMenu:forTableColumn:
方法。根据需要启用/禁用菜单项(确保菜单在IB中不会自动验证)。将所点击的列存储在实例变量中,以便在用户选择操作时知道要处理哪一列。
PGETableViewTableHeaderView.h#import <Cocoa/Cocoa.h>
@protocol PGETableViewTableHeaderViewDelegate <NSObject>
-(void)validateMenu:(NSMenu*)menu forTableColumn:(NSTableColumn*)tableColumn;
@end
@interface PGETableViewTableHeaderView : NSTableHeaderView
@property(weak) IBOutlet id<PGETableViewTableHeaderViewDelegate> delegate;
@end
PGETableViewTableHeaderView.m
#import "PGETableViewTableHeaderView.h"
@implementation PGETableViewTableHeaderView
-(NSMenu *)menuForEvent:(NSEvent *)event {
NSInteger columnForMenu = [self columnAtPoint:[self convertPoint:event.locationInWindow fromView:nil]];
NSTableColumn *tableColumn = nil;
if (columnForMenu >= 0) tableColumn = self.tableView.tableColumns[columnForMenu];
NSMenu *menu = self.menu;
[self.delegate validateMenu:menu forTableColumn:tableColumn];
return menu;
}
@end
protocol IMenuTableHeaderViewDelegate: class {
func menuForTableHeader(inTableView tableView: NSTableView, forTableColumn tableColumn: NSTableColumn) -> NSMenu?
}
class MenuTableHeaderView: NSTableHeaderView {
weak var menuDelegate: IMenuTableHeaderViewDelegate?
override func menu(for event: NSEvent) -> NSMenu? {
guard tableView != nil else {
return nil
}
let columnForMenu = column(at: convert(event.locationInWindow, from: nil))
if columnForMenu >= 0, tableView!.tableColumns.count > columnForMenu {
if let tableColumn = tableView?.tableColumns[columnForMenu] {
return menuDelegate?.menuForTableHeader(inTableView: tableView!, forTableColumn: tableColumn)
}
}
return self.menu;
}
}
要使用这个自定义类,请在界面构建器中找到NSTableHeaderView并将其更改为MenuTableHeaderView
在ViewController中使用此方法的示例
class ExampleViewController: NSViewController, IMenuTableHeaderViewDelegate {
@IBOutlet weak var tableView: NSTableView!
@IBOutlet var tableHeaderMenu: NSMenu!
var lastColumnForMenu: HeaderColumnForMenu?
struct HeaderColumnForMenu {
let tableView: NSTableView
let tableColumn: NSTableColumn
}
override func viewDidLoad() {
super.viewDidLoad()
if let tableHeaderWithMenu = tableView.headerView as? MenuTableHeaderView {
tableHeaderWithMenu.menuDelegate = self
}
}
func menuForTableHeader(inTableView tableView: NSTableView, forTableColumn tableColumn: NSTableColumn) -> NSMenu? {
//Save column to wich we are going to show menu
lastColumnForMenu = HeaderColumnForMenu(tableView: tableView, tableColumn: tableColumn)
if needShowMenu {
return tableHeaderMenu
}
return nil
}
}
[yourTableView clickedColumn]
。 - Julian F. Weinert