基于视图的NSOutlineView中的空单元格

3

更新: 完整源代码下载链接 (下载)

我正在尝试实现一个基于视图的NSOutlineView (Sourcelist),但是我遇到了问题。为了说明问题,我创建了一个最简示例。

我有一个名为Person的简单类。每个人都有一个名字(NSString),可能还有一些孩子(NSArray)。我添加了一个NSOutlineView,将其连接到IBOutlet,将自己设置为DataSource,并实现了NSOutlineViewDataSource方法。

首先考虑基于CELL的NSOutlineView的情况:

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    // We are at the root
    if (!item)
    {
        return [self.persons count];

    }

    // We are at an internal node
    Person *person = (Person *)item;
    return [person.children count];
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
    // We are at the root
    if (!item)
    {
        return self.persons[index];
    }

    // We are at an internal node
    Person *person = (Person *)item;
    return person.children[index];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
    Person *person = (Person *)item;
    if ([person.children count] > 0)
    {
        return YES;
    }
    return NO;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    Person *person = (Person *)item;
    return person.name;
}

它的工作方式与我预期的一样:

enter image description here

然而,如果我将NSOutlineView更改为基于视图的VIEW BASED,则情况会有很大不同。现在所有名称都被“表格视图单元格”替换。我尝试通过返回NSTableCellView来解决问题:

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    Person *person = (Person *)item;

    NSTableCellView *tableCellView = [outlineView makeViewWithIdentifier:@"PersonCell" owner:self];
    tableCellView.textField.stringValue = person.name;

    return tableCellView;
}

不做进一步更改,这不会改变任何事情。当我将NSOutlineView中的TableCellView的标识符更改为PersonCell时,所有单元格都变为空白。事实上,在outlineView:objectValueForTableColumn:byItem:函数中添加一个简单的NSLog语句会发现该函数甚至从未被调用过。
这种方法在标准NSTableView中对我有效,而且由于NSOutlineView是NSTableView的子类,我期望在这里也有相同的行为。
非常感谢您的帮助。
谢谢!
/Michael Knudsen
1个回答

4

我认为返回每行正确的视图对象的对应方法是

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

而不是

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item

在基于视图的表视图中,您需要返回一个视图而不是一个对象值。

因此,应该使用以下方式来使其工作:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
    Person *person = (Person *)item;
    NSTableCellView *tableCellView = [outlineView makeViewWithIdentifier:@"PersonCell" owner:self];
    tableCellView.textField.stringValue = person.name;

    return tableCellView;
}

嗨,感谢您的尝试帮助。不幸的是,该方法仍未被调用。我觉得这非常、非常奇怪... - Michael Knudsen
我已在原帖中添加了源代码的链接。 - Michael Knudsen
2
重新阅读您的帖子,我发现可能缺少委托连接?上面的方法是一个委托而不是数据源方法! - Volker
嗯嗯嗯。实际上,这个方法是一个数据源方法,而不是委托方法。然而,将self设置为委托仍然解决了问题。我很困惑为什么会这样。我没有实现NSOutlineViewDelegate协议中列出的任何一个方法。 - Michael Knudsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接