Ответ 1
Получить NSTableHeaderView из NSTableView и настроить его.
[[myTableView headerView] setMenu:aMenu];
Я ищу элегантный способ обнаружения щелчка правой кнопкой мыши /ctrl -click в заголовке NSTableView.
При щелчке правой кнопкой мыши я хочу отобразить контекстное меню.
- (NSMenu *)menuForEvent:(NSEvent *)
обнаруживает только правые клики в таблице - не в заголовке таблицы.
спасибо за вашу помощь.
Получить NSTableHeaderView из NSTableView и настроить его.
[[myTableView headerView] setMenu:aMenu];
Иногда изображение объясняет 1000 слов.
На любом столеView вы можете выбрать TableView и подключить выход в меню к меню.
Теперь вы можете подключить селектор меню (справа) к вашему коду.
[yourTableView clickedRow]
Готово. Как босс.
Вам нужно подклассом 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
Спасибо Якобу Эггеру за его точный ответ. Я придумал версию Swift этого подхода. Я немного изменил подпись метода делегата, чтобы обеспечить большую гибкость в случае более одного TableView в ViewController.
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
}
}