在基于视图的NSOutlineView中未为子项调用viewForTableColumn [英] viewForTableColumn not being called for child items in view-based NSOutlineView

查看:56
本文介绍了在基于视图的NSOutlineView中未为子项调用viewForTableColumn的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法

 -(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn项目:(id)项目; 

该项目不是分组项目时,不会调用

.方法

 -(BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)项目;-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item; 

实施

可以为(相同和)正确的页眉/组项目集返回YES.下列方法

 -(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)项目;-(id)outlineView:(NSOutlineView *)outlineView子项:(NSInteger)childIndex ofItem:(id)item; 

还分别返回子项和有效子项的明智计数.但是,从未为子项调用上述 outlineView:viewForTableColumn:item:方法.这些行是为子级布置的,但它们是空白的(如下面的屏幕快照所示),因为从未为子级调用视图生成方法 outlineView:viewForTableColumn:item:.

请注意,我没有任何XIB,并且所有视图均以编程方式进行布局.特别是,这意味着我无法通过XIB在大纲视图的基础表视图上为内容模式"设置基于视图的"值,就像在 https://developer.apple.com/library/mac/samplecode/SidebarDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010893 .

如果可以通过编程的方式进行此操作,那将是一个很大的帮助.尽管由于对父项调用了view方法,所以不确定这是否是 real 问题.

我的另一个奥秘是以下两种方法返回的视图如何相互配合:

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

解决此问题的任何线索都会有很大帮助吗?

解决方案

以下是我整理的一些代码,用以显示-(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn项:(id)项目;确实被调用.也许通过查看它,您可能会在某个地方看到错误:

 //AppDelegate.m#import"AppDelegate.h"#import"Item.h"@interface AppDelegate()@property(strong)NSMutableArray *项目;@属性(弱)IBOutlet NSWindow *窗口;@结尾@implementation AppDelegate-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {//在此处插入代码以初始化您的应用程序self.items = [NSMutableArray array];项目* group1 = [项目itemWithName:@组1"];[group1 addChild:[Item itemWithName:@"0,0"]]];[group1 addChild:[Item itemWithName:@"1,0"]]];[group1 addChild:[Item itemWithName:@"2,0"]]];项目* group2 = [项目itemWithName:@组2"];[group2 addChild:[Item itemWithName:@"0,1"]];[group2 addChild:[Item itemWithName:@"1,1"]]];[group2 addChild:[Item itemWithName:@"2,1"]]];项目* group3 = [项目itemWithName:@组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 {返回!item.parent;}-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(Item *)item {返回item.children.count;}-(id)outlineView:(NSOutlineView *)outlineView子项:(NSInteger)Item:(Item *)item的索引{如果(!item){返回self.items [index];}如果(item.children.count>索引)返回item.children [index];返回零;}-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(Item *)item {如果(!item){返回self.items.count;}返回item.children.count;}-(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(Item *)item {//此处设置的断点进行测试返回[[NSView alloc] init];}@结尾//Item.h@interface项目:NSObject@属性(弱)项目*父级;@property(副本)NSString *名称;+(instancetype)itemWithName:(NSString *)name;-(instancetype)initWithName:(NSString *)name;-(void)addChild:(Item *)child;-(void)removeChild:(Item *)child;@结尾@interface项目(属性)@property(只读,强壮的)NSArray * children;@结尾//Item.m#import"Item.h"@interface项()@property(读写,强壮)NSMutableArray * children;@结尾@实施项目+(instancetype)itemWithName:(NSString *)name {返回[[self alloc] initWithName:name];}-(instancetype)initWithName:(NSString *)name {如果((self = [self init])){self.name =名称;}回归自我}-(id)init {如果((self = [super init])){self.name = @没有名字";self.children = [NSMutableArray array];}回归自我}-(void)addChild:(Item *)child {child.parent =自我;[self.children addObject:child];}-(void)removeChild:(Item *)child {如果(child.parent == self)child.parent =零;[self.children removeObject:child];}@结尾 

关于NSTableView/NSOutlineView基于视图的状态的第二个问题:该值是根据实现的委托/数据源方法自动设置的.如果要实现-(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:{id)item; ,则该视图将被视为基于视图的./p>

关于这两个问题,您的最后一个问题:

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

第二种方法涉及跨表宽度的视图,其中包含每个表列的单元格视图.这意味着您有几种单元格视图(每列一个单元格视图)是第一种方法返回的,它们是第二种视图每行返回的一个视图的子视图.

I have an issue that the method

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

is not being called when the item isn't a group item. The methods

-(BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item;
-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;

are implemented to return YES for the (same and) correct set of header/group items. The following methods

-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item;
-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)childIndex ofItem:(id)item;

also return sensible count for children and valid child items respectively. But the above outlineView:viewForTableColumn:item: method is never called for child items. The rows are laid out for children, but are blank (as shown in the screenshot below) since the view-generating method outlineView:viewForTableColumn:item: is never called for children.

Note that I do not have any XIBs and all views are laid out programmatically. In particular, this means I cannot set 'View Based' value for Content Mode on the outline view's underlying table view via the XIB as done in the Apple example code at https://developer.apple.com/library/mac/samplecode/SidebarDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010893 .

If there's a way to do this programmatically, it would be a great help. Although since the view method is called for parent items, not sure if this is the real problem.

Another mystery for me is how the views returned by the following two methods work with each other:

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

Any clues on fixing this would be a great help?

解决方案

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.

这篇关于在基于视图的NSOutlineView中未为子项调用viewForTableColumn的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆