我正在尝试在表格视图中创建自定义弹出菜单。据我了解,我应该可以通过调用自定义视图中传递的 [NSPopupButtonCell setView:myView] 方法来做到这一点(这只是一个带有 NSOutlineView 的 NSView)。
所以我创建了一个 NSPopupButtonCell 子类,在初始化期间我调用 setView 并传入自定义大纲视图..
编辑
在 IB 中,我将表格列单元格设置为弹出按钮单元格,并将类设置为我的自定义 LookupPopupButtonCell。
我仍然没有显示我的自定义视图,但我的自定义类初始化方法似乎被调用了。
我已经用 NSTableViewDelegate 方法 dataCellForTableColumn 替换了这种方法。现在弹出窗口显示了我的自定义 tableView。
尽管如此,调用 NSOutlineViewDelegate 方法仍然没有乐趣。
编辑好的我已经设法在视图上使用 NSPopupButton 使事情正常进行。委托工作查找和表格视图显示的东西很好。似乎使用 NSPopupButtonCell 委托方法永远不会被调用。
@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