你如何添加到右键单击一个行中的NSOutlineView所以可以说删除对象或其他活动的能力。 (即就像当你右键点击在苹果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];
}
在你menuForEvent方法,你可以找出发生在哪一行的点击。 您可以传递一个作为参数传递给你的defaultMenu方法-也许称之为defaultMenuForRow:
-(NSMenu*)menuForEvent:(NSEvent*)evt
{
NSPoint pt = [self convertPoint:[evt locationInWindow] fromView:nil];
int row=[self rowAtPoint:pt];
return [self defaultMenuForRow:row];
}
现在,您可以为您构建在事件中发现该行的菜单...
-(NSMenu*)defaultMenuForRow:(int)row
{
if (row < 0) return nil;
NSMenu *theMenu = [[[NSMenu alloc]
initWithTitle:@"Model browser context menu"]
autorelease];
[theMenu insertItemWithTitle:@"Add package"
action:@selector(addSite:)
keyEquivalent:@""
atIndex:0];
[theMenu insertItemWithTitle:[NSString stringWithFormat:@"Remove '%i'", row]
action:@selector(removeSite:)
keyEquivalent:@""
atIndex:0];
// you'll need to find a way of getting the information about the
// row that is to be removed to the removeSite method
// assuming that an ivar 'contextRow' is used for this
contextRow = row;
return theMenu;
}
此外,如在评论中已经提到的,你真的不应该用你自己的类NS-前缀。 有在未来再加上它会混淆大家的冲突潜在的是看你的代码 - 包括你自己:)
希望这可以帮助...
下面是使用一个子类,并扩展了默认的一个雨燕2.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!)
}
}
很久以后比OP的问题,但对于其他人一样我想知道,这里是我的解决方案。 它还需要继承NSOutlineView,这不是苹果的文档鼓励,反正...
而不是覆盖menuForEvent:
我重写rightMouseDown:
- (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];
}
这有保持委托的优势,此后调用更新菜单,也保留行概述了点击右键。
如果你愿意,你可以将菜单中的单个细胞视图或行观点,并与界面生成器生成它:
@implementation BSMotleyOutlineView
-(NSMenu *)menuForEvent:(NSEvent *)event
{
NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil];
NSInteger row = [self rowAtPoint:pt];
if (row >= 0) {
NSTableRowView* rowView = [self rowViewAtRow:row makeIfNecessary:NO];
if (rowView) {
NSInteger col = [self columnAtPoint:pt];
if (col >= 0) {
NSTableCellView* cellView = [rowView viewAtColumn:col];
NSMenu* cellMenu = cellView.menu;
if(cellMenu) {
return cellMenu;
}
}
NSMenu* rowMenu = rowView.menu;
if (rowMenu) {
return rowMenu;
}
}
}
return [super menuForEvent:event];
}
@end
文章来源: How do you add context senstive menu to NSOutlineView (ie right click menu)