如何在NSOutlineView中添加右键单击一行的功能,这样就可以删除对象或其他活动。(例如,当你在Apple Mail应用程序中右键点击文件夹时)
我想我已经完成了一半,我有一个NSOutlineView的子类,它允许我捕捉右键单击,并根据选定的行显示上下文菜单,而不是鼠标单击的行。
@implementation NSContextOutlineView
- (NSMenu *)defaultMenu {
if([self selectedRow] < 0) return nil;
NSMenu *theMenu = [[[NSMenu alloc] initWithTitle:@"Model browser context menu"] autorelease];
[theMenu insertItemWithTitle:@"Add package" action:@selector(addSite:) keyEquivalent:@"" atIndex:0];
NSString* deleteItem = [NSString stringWithFormat: @"Remove '%i'", [self selectedRow]];
[theMenu insertItemWithTitle: deleteItem action:@selector(removeSite:) keyEquivalent:@"" atIndex:1];
return theMenu;
}
- (NSMenu *)menuForEvent:(NSEvent *)theEvent {
return [self defaultMenu];
}
@end
抱歉,如果答案是显而易见的,我只是找不到任何关于这个在线或在文档中的帮助。
多亏了Void的回答,它引导我使用了以下内容:
- (NSMenu *)menuForEvent:(NSEvent *)theEvent {
NSPoint pt = [self convertPoint:[theEvent locationInWindow] fromView:nil];
id item = [self itemAtRow: [self rowAtPoint:pt]];
return [self defaultMenuFor: item];
}
发布于 2015-09-22 21:43:10
下面是一个SWIFT2.0示例,它使用了一个子类并扩展了默认的NSOutlineDelegate
,这样您就可以在委托中定义您的菜单。
protocol MenuOutlineViewDelegate : NSOutlineViewDelegate {
func outlineView(outlineView: NSOutlineView, menuForItem item: AnyObject) -> NSMenu?
}
class MenuOutlineView: NSOutlineView {
override func menuForEvent(event: NSEvent) -> NSMenu? {
let point = self.convertPoint(event.locationInWindow, fromView: nil)
let row = self.rowAtPoint(point)
let item = self.itemAtRow(row)
if (item == nil) {
return nil
}
return (self.delegate() as! MenuOutlineViewDelegate).outlineView(self, menuForItem: item!)
}
}
发布于 2018-12-13 22:45:39
比OP问题晚得多,但对于像我这样想知道的人来说,这是我的解决方案。它还需要对NSOutlineView进行子类化,这是苹果文档不鼓励的,不管怎么说,…
我覆盖了rightMouseDown:
,而不是覆盖menuForEvent:
- (void)rightMouseDown:(NSEvent *)event {
NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil];
NSInteger row = [self rowAtPoint:pt];
id item = [self itemAtRow:row];
NSMenu *menu;
//set the menu to one you have defined either in code or IB through outlets
self.menu = menu;
[super rightMouseDown:event];
}
这具有保留委托调用以更新菜单的优点,并且还可以在右击时保持行轮廓。
发布于 2020-12-02 18:09:50
不需要子类化,它非常简单,你甚至可以在飞行中定制菜单。
声明一个空菜单,设置它的委托,并在outline views .menu
属性上设置它。作为一个额外的好处,这个方法在大纲视图和表视图上都有效。
class OutlineViewController: NSViewController {
private let contextMenu = NSMenu(title: "Context")
override func viewDidLoad() {
super.viewDidLoad()
// other init stuff...
contextMenu.delegate = self
outlineView.menu = contextMenu
}
}
extension OutlineViewController: NSMenuDelegate {
func menuNeedsUpdate(_ menu: NSMenu) {
// Returns the clicked row indices.
// If the right click happens inside a selection, it is usually
// the selected rows, if it appears outside of the selection it
// is only the right clicked row with a blue border, as defined
// in the `NSTableView` extension below.
let indexes = outlineView.contextMenuRowIndexes
menu.removeAllItems()
// TODO: add/modify item as needed here before it is shown
}
}
extension NSTableView {
var contextMenuRowIndexes: IndexSet {
var indexes = selectedRowIndexes
// The blue selection box should always reflect the returned row indexes.
if clickedRow >= 0
&& (selectedRowIndexes.isEmpty || !selectedRowIndexes.contains(clickedRow)) {
indexes = [clickedRow]
}
return indexes
}
}
https://stackoverflow.com/questions/1309602
复制相似问题