viewForTableColumn not being called for child items in view-based NSOutlineView

亡梦爱人 提交于 2019-12-06 14:51:01

Here is some code I put together to show that -(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item; does get called. Maybe by looking at it you could see an error you made somewhere:

// AppDelegate.m

#import "AppDelegate.h"
#import "Item.h"

@interface AppDelegate ()

@property (strong) NSMutableArray *items;
@property (weak) IBOutlet NSWindow *window;

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    self.items = [NSMutableArray array];

    Item *group1 = [Item itemWithName:@"GROUP 1"];
    [group1 addChild:[Item itemWithName:@"0,0"]];
    [group1 addChild:[Item itemWithName:@"1,0"]];
    [group1 addChild:[Item itemWithName:@"2,0"]];

    Item *group2 = [Item itemWithName:@"GROUP 2"];
    [group2 addChild:[Item itemWithName:@"0,1"]];
    [group2 addChild:[Item itemWithName:@"1,1"]];
    [group2 addChild:[Item itemWithName:@"2,1"]];

    Item *group3 = [Item itemWithName:@"GROUP 3"];
    [group3 addChild:[Item itemWithName:@"0,2"]];
    [group3 addChild:[Item itemWithName:@"1,2"]];
    [group3 addChild:[Item itemWithName:@"2,2"]];

    [self.items addObject: group1];
    [self.items addObject: group2];
    [self.items addObject: group3];

    [self.souceList reloadData];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(Item *)item {
    return !item.parent;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(Item *)item {
    return item.children.count;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(Item *)item {
    if (!item) {
        return self.items[index];
    }

    if (item.children.count > index)
        return item.children[index];
    return nil;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(Item *)item {
    if (!item) {
        return self.items.count;
    }
    return item.children.count;
}

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(Item *)item {
    // Breakpoint set here to test
    return [[NSView alloc] init];
}

@end

// Item.h
@interface Item : NSObject
@property (weak) Item *parent;
@property (copy) NSString *name;

+ (instancetype)itemWithName:(NSString *)name;
- (instancetype)initWithName:(NSString *)name;

- (void)addChild:(Item *)child;
- (void)removeChild:(Item *)child;

@end

@interface Item (Property)
@property (readonly, strong) NSArray *children;
@end

// Item.m

#import "Item.h"

@interface Item ()
@property (readwrite, strong) NSMutableArray *children;
@end

@implementation Item

+ (instancetype)itemWithName:(NSString *)name {
    return [[self alloc] initWithName:name];
}

- (instancetype)initWithName:(NSString *)name {
    if ((self = [self init])) {
        self.name = name;
    }
    return self;
}

- (id)init {
    if ((self = [super init])) {
        self.name = @"No Name";
        self.children = [NSMutableArray array];
    }
    return self;
}

- (void)addChild:(Item *)child {
    child.parent = self;
    [self.children addObject: child];
}
- (void)removeChild:(Item *)child {
    if (child.parent == self)
        child.parent = nil;
    [self.children removeObject:child];
}

@end

Regarding your second question about the View-based status of NSTableView/NSOutlineView: that value is set automatically depending upon which delegate/datasource methods are implemented. If you are implementing -(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item;, then the view will be treated as view-based.

As for your last question regarding these two:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item;
- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item;

The second method relates to a view which spans the width of the table, encompassing the cell views for every table column. Meaning you have several cell views - one for each column - returned by the first method which are subviews of the one view returned by the second for each row.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!