我有一个基于文档的核心数据应用程序,带有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自动完成这种样式,但我不认为这是可能的 - 是吗?
答案 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;
}
}
咄!