2013-08-13 2 views
0

테이블 뷰에서 사용자 지정 팝업 메뉴를 만들려고합니다. 내가 이해할 수있는 것처럼 [NSPopupButtonCell setView : myView] 메서드를 호출하여 사용자 정의 뷰 (NSView에 NSOutlineView가있는)에 전달하면이 작업을 수행 할 수 있어야합니다.NSTableView의 사용자 지정 NSPopupButtonCell

그래서 나는 NSPopupButtonCell 서브 클래스를 생성하고

편집 .. 초기화하는 동안 나는 setView를 호출하고 사용자 정의 개요보기를 전달 나는 팝업 버튼에 테이블 열 셀을 설정 한 IB에서

셀을 열고 내 맞춤 LookupPopupButtonCell에 클래스를 설정하십시오.

아직 내 사용자 지정보기가 표시되지 않지만 사용자 지정 클래스 초기화 메서드가 호출되는 것으로 보입니다.

이후 NSTableViewDelegate 메소드 dataCellForTableColumn을 사용하여이 접근 방식을 대체했습니다. 이제 팝업이 내 사용자 정의 tableView를 보여줍니다.

그래도 NSOutlineViewDelegate 메소드를 가져 오는 데 큰 기쁨이 없습니다.

EDIT 확인보기에서 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 
+0

내가 뭔가 ==> 코드 –

+0

추가 코드를 놓친 거지. LookupPopupButtonCell은 NSPopupButtonCell의 하위 클래스입니다. 팝업이 작동하는 것으로 보이고 tableview를 보여 주지만 뷰에는 데이터가 없습니다. reloadData를 호출하면 DataSource 메서드가 호출됩니다. selectRowIndexes를 호출하면 outlineViewSelectionDidChange가 호출됩니다 (mmm 데이터 소스가 아닌 Delegate 콜백이라고 생각합니다). –

답변

0

대리자 메시지를 가져 오기 위해서는 VIEW 기반 tableView를 사용해야합니다. Blah, 이제 Core Data에 바인딩하는 방법을 알아 냈습니다.

각 행에 대해 동일한 메뉴를 재사용 할 수있는 방법이 있습니까? 아마 dataSource가 너무 나쁘지는 않을 때마다 다시 만들어지지 않는 한이 계층 구조에 많은 행이있을 수 있습니다.

Outline view in tableView popup menu

관련 문제