造型NSOutlineView行

时间:2014-07-19 23:05:06

标签: core-data background nsoutlineview nstreecontroller nstablerowview

我有一个基于文档的核心数据应用程序,带有NSTreeController,将内容提供给基于NSOutlineView的视图。我是"造型" (设置文本颜色,背景颜色等)基于持久性"可变形"的行。 NSColor和NSFont属性在我的数据模型中,最终用户可以修改。弹出新行时,它会显示数据模型中设置的颜色/字体。以下是设置行背景颜色的委托/数据源代码:

- (void) outlineView:(NSOutlineView *)outlineView
       didAddRowView:(NSTableRowView *)rowView
              forRow:(NSInteger)row
{
    // Get the relevant nodeType which contains the attributes
    QVItem *aNode = [[outlineView itemAtRow:row] representedObject];
    if (aNode.backColor)
    {
        rowView.backgroundColor = aNode.backColor;
    }
}

但是,当样式属性发生更改时,我希望使用新样式值重新绘制关联的可见行。每一次"风格"属性已更改,我正在使用NSNotificationCenter向Outline视图委托发送通知,其中模型对象的行需要使用更改的样式重绘。这是接收通知的委托中的代码。

-(void) styleHasChanged: (NSNotification *)aNotification
{
    NSTreeNode *aTreeNode = [myTreeController treeNodeForModelObject:aNotification.object];
    [myOutlineView reloadItem:aTreeNode];
}

我的假设是我可以导航树控制器以找到表示我的模型对象的树节点,然后请求大纲视图重绘该树节点的行。这是"添加"树控制器中的代码遍历树以找到对象 - 不是非常有效,但我认为还有另一种方式。

@implementation NSTreeController (QVAdditions)

- (NSTreeNode *)treeNodeForModelObject:(id)aModelObject
{
    return [self treeNodeForModelObject:aModelObject inNodes:[[self arrangedObjects] childNodes]];
}

- (NSTreeNode *)treeNodeForModelObject:(id)aModelObject inNodes:(NSArray*)nodes
{
    for(NSTreeNode* node in nodes)
    {
        if([node representedObject] == aModelObject)
            return node;
        if([[node childNodes] count])
        {
            NSTreeNode * treeNode = [self treeNodeForModelObject:aModelObject inNodes:[node childNodes]];
            return treeNode;
        }
    }
    return nil;
}

所以有时候这会有效并且行会重绘,有时它也不会重新绘制。委托方法" styleHasChanged:"始终调用,树控制器始终返回相应的树节点(实际上是NSTreeNode的子类)。但通常情况下,大纲视图无法识别树节点,并且不会重绘该行。就像树控制器已经将过去给出轮廓视图的树节点对象一样。但奇怪的是,它有时会起作用,右侧的行会重新绘制新的背景颜色。如果我将行折叠出视图并再次将其弹出,则会正确重绘。

任何人都知道为什么它有时会起作用而不是其他时间?

能够以某种方式将颜色/字体属性绑定到行和列是很好的,这样大纲视图就可以使用KVO自动完成这种样式,但我不认为这是可能的 - 是吗?

1 个答案:

答案 0 :(得分:0)

你花费数小时/天试图弄清楚你做错了什么;你把问题写出来;发表它;睡在上面;并认为你是多么愚蠢。

所以我要求NSTableRowView重绘自己,但我没有设置新的背景颜色。所以这里是styleHasChanged的新改进版(和作品版):

-(void) styleHasChanged: (NSNotification *)aNotification
{
    QVItem *modelItem = aNotification.object;
    NSTreeNode *aTreeNode = [myTreeController treeNodeForModelObject:modelItem];
    NSInteger rowIndex = [myOutlineView rowForItem:aTreeNode];
    if !(rowIndex == -1)
    {
        NSTableRowView *rowViewToBeUpdated = [myOutlineView rowViewAtRow:rowIndex makeIfNecessary:YES];
        rowViewToBeUpdated.backgroundColor = modelItem.backColor;
    }
}

咄!