Objective c NSTableView中的自定义NSPopupButtonCell
我正在尝试在tableview中创建自定义弹出菜单。据我所知,我应该能够通过调用传入自定义视图的[NSPopupButtonCell setView:myView]方法来实现这一点(这只是一个包含NSOutlineView的NSView) 因此,我创建了一个NSPopupButtonCell子类,在初始化过程中,我调用setView并传入自定义大纲视图 编辑 在IB中,我将表格列单元格设置为弹出按钮单元格,并设置 我的自定义LookupPopupButtonCell的类 我仍然无法显示自定义视图,但可以显示自定义类 初始化方法似乎正在被调用 此后,我使用NSTableViewDelegate方法dataCellForTableColumn取代了这种方法。现在,弹出窗口显示我的自定义表视图 不过,调用NSOutlineViewDelegate方法仍然没有乐趣 编辑 好的,我已经通过在视图上使用NSpoupButton成功地使事情正常工作。委托工作查找和表视图显示良好。似乎使用NSPopupButtonCell委托方法永远不会被调用Objective c NSTableView中的自定义NSPopupButtonCell,objective-c,cocoa,nspopupbuttoncell,Objective C,Cocoa,Nspopupbuttoncell,我正在尝试在tableview中创建自定义弹出菜单。据我所知,我应该能够通过调用传入自定义视图的[NSPopupButtonCell setView:myView]方法来实现这一点(这只是一个包含NSOutlineView的NSView) 因此,我创建了一个NSPopupButtonCell子类,在初始化过程中,我调用setView并传入自定义大纲视图 编辑 在IB中,我将表格列单元格设置为弹出按钮单元格,并设置 我的自定义LookupPopupButtonCell的类 我仍然无法显示自定义视图
@implementation LookupPopupButtonCell
- (id)init
{
LOG(@"init called");
self = [super init];
if (self) {
[self initialise];
}
return self;
}
- (void)initialise
{
LOG(@"initialise called");
[self setFont:[NSFont fontWithName:@"System Regular" size:11]];
[self setBordered:NO];
[self setBezeled:NO];
// Set the Task Lookup Popup Menu
NSMenu *newLookupMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Custom"];
NSMenuItem *newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Lookup" action:nil keyEquivalent:@""];
[newItem setEnabled:YES];
TaskLookupViewController *viewController = [[TaskLookupViewController alloc] initWithNibName:@"TaskLookupViewController" bundle:nil];
[newItem setView:[viewController view]];
[newLookupMenu addItem:newItem];
[newItem release];
[self setMenu:newLookupMenu];
}
@end
@implementation TaskLookupViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code here.
[self initialise];
}
return self;
}
- (void)awakeFromNib{
LOG(@"awakeFromNib called...");
[self viewDidLoad];
}
- (void)viewDidLoad {
FLOG(@"viewDidLoad called for %@", self);
/*
FLOG(@" _outlineView is %@", _outlineView);
FLOG(@" _outlineView is %@", [_outlineView identifier]);
FLOG(@" _outlineView delegate is %@", [_outlineView delegate]);
FLOG(@" _outlineView dataSource is %@", [_outlineView dataSource]);
*/
[_outlineView setDataSource:self];
[_outlineView setDelegate:self];
[_outlineView reloadData];
[_outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
[_outlineView setNeedsDisplay];
[_outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:2] byExtendingSelection:NO];
/*
FLOG(@" _outlineView delegate is %@", [_outlineView delegate]);
FLOG(@" _outlineView dataSource is %@", [_outlineView dataSource]);
*/
//NSTableColumn *tableColumn = [[_outlineView tableColumns] objectAtIndex:0];
//LOG(@" setting bindings");
//[tableColumn bind: @"value" toObject: _treeController withKeyPath: @"arrangedObjects.displayName" options: nil];
}
- (void)initialise {
LOG(@"initialise called");
_topLevelItems = [[NSArray arrayWithObjects:@"Project", @"Tasks and Deliverables", @"Finance", nil] retain];
_childrenDictionary = [NSMutableDictionary new];
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"Scope", nil] forKey:@"Project"];
//[_childrenDictionary setObject:[NSArray arrayWithObjects:@"Issues", @"Risks", nil] forKey:@"Quality"];
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"WBS", @"Functions", nil] forKey:@"Tasks and Deliverables"];
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"Expenses", @"Ongoing Costs", @"Timesheets", nil] forKey:@"Finance"];
//[_childrenDictionary setObject:[NSArray arrayWithObjects:@"Applications", @"Interfaces", nil] forKey:@"IT Systems"];
//[_childrenDictionary setObject:[NSArray arrayWithObjects:@"People", @"Setup", nil] forKey:@"Administration"];
}
- (NSArray *)_childrenForItem:(id)item {
LOG(@"_childrenForItem called");
NSArray *children;
if (item == nil) {
children = _topLevelItems;
} else {
children = [_childrenDictionary objectForKey:item];
}
//FLOG(@" children are %@", children);
return children;
}
@end
@implementation TaskLookupViewController (NSOutlineViewDataSource)
- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
LOG(@"outlineViewSelectionDidChange: called");
if ([_outlineView selectedRow] != -1) {
NSObject *item = [_outlineView itemAtRow:[_outlineView selectedRow]];
if ([_outlineView parentForItem:item] != nil) {
// Only change things for non-root items (root items can be selected, but are ignored)
FLOG(@" selected item is %@", item);
}
}
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
FLOG(@"outlineView:child:ofItem: called for item %@", item);
return [[self _childrenForItem:item] objectAtIndex:index];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
LOG(@"outlineView:isItemExpandable: called");
if ([outlineView parentForItem:item] == nil) {
return YES;
} else {
return YES;
}
}
- (NSInteger) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
LOG(@"outlineView:numberOfChildrenOfItem: called");
FLOG(@" children count is %d", [[self _childrenForItem:item] count]);
return [[self _childrenForItem:item] count];
}
@end
@implementation TaskLookupViewController (NSOutlineViewDelegate)
- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
LOG(@"outlineView:isGroupItem: called");
return [_topLevelItems containsObject:item];
}
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
LOG(@"willDisplayCell called");
[cell setTitle:@"Cell Title"];
}
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
LOG(@"outlineView:viewForTableColumn called");
// We just return a regular text view.
if ([_topLevelItems containsObject:item]) {
NSTextField *result = [outlineView makeViewWithIdentifier:@"HeaderTextField" owner:self];
// Uppercase the string value, but don't set anything else. NSOutlineView automatically applies attributes as necessary
NSString *value = [item uppercaseString];
[result setStringValue:value];
return result;
} else {
NSTextField *result = [outlineView makeViewWithIdentifier:@"ItemTextField" owner:self];
[result setStringValue:value];
return result;
}
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item;
{
LOG(@"outlineView:shouldExpandItem: called");
return YES;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;
{
LOG(@"outlineView:shouldSelectItem: called");
return YES;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldCollapseItem:(id)item;
{
LOG(@"outlineView:shouldCollapseItem: called");
return NO;
}
@end
@implementation TaskLookupViewController (NSTableViewDelegate)
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
LOG(@"tableView:dataCellForTableColumn:row: called");
NSString *identifier = [tableColumn identifier];
if ([identifier isEqualToString:@"task"]) {
//LOG(@" task column setting the cell");
LookupPopupButtonCell *cellView = [[LookupPopupButtonCell alloc] init];
return cellView;
}
NSTextFieldCell *cellView = [tableView makeViewWithIdentifier:@"hoursCell" owner:self];
return cellView;
}
@end
似乎必须使用基于视图的tableView来获取代理消息。诸如此类,现在要弄清楚如何将其中一个绑定到核心数据,希望不是太难 有没有办法对每一行重复使用相同的菜单?我想,只要每次都不重新创建数据源,这可能还不算太糟糕,但在这个层次结构中仍然可能有很多行
我是否缺少一些东西==>代码添加了代码。LookupPopupButtonCell是NSPopupButtonCell的子类。注意:弹出窗口似乎可以工作并显示tableview,但视图中没有数据。调用reloadData会导致调用DataSource方法。调用selectRowIndexes还会导致调用outlineViewSelectionDidChange(嗯,我认为这是一个委托回调,而不是数据源)。