让我们假设在您的 NSOutlineView 中有一个 childrenKeyPath 为“children”,并且孩子有一个布尔 isNew 属性。你想要的是一个漂亮的numberOfNewItems 气泡在一个对象类的单元格视图中。我将其称为父对象。
如果您只想要 childrenKeyPath 中的对象数量,哎呀,这更容易,但我将带您了解更复杂的情况,即跟踪子项上的特定布尔属性,因为它很容易简化这种模式。
在父对象的表格单元格视图中添加一个嵌入式按钮,其中title绑定到objectValue.numberOfNewItems,hidden绑定到@ 987654324@ 带有值转换器 NSNegateBoolean。如果您只想要孩子的数量,请将这些键路径切换到objectValue.children.count,然后就完成了。如果你想跟踪 isNew 这样的属性,让我们继续...
在父对象类中,有这样的代码:
- (NSNumber*) numberOfNewItems
{
// Collection operator on boolean returns total number of new children
return [self valueForKeyPath:@"children.@sum.isNew"];
}
// This setter does nothing, but with KVO it causes bindings
// to numberOfNewItems to call the above getter
- (void) setNumberOfNewItems:(NSNumber*)number { }
// This ensures that changes to the children set causes KVO calls to the above getter
+ (NSSet*) keyPathsForValuesAffectingNumberOfNewItems
{
return [[NSSet alloc] initWithObjects:@"children", nil];
}
这样做会导致在表格单元格的 objectValue 将新子元素添加到其 children 对多关系中或从中删除时重新计算 numberOfNewItems。
在 childItem 类中,childItem 从 isNew 转换为 not-New 的地方有一个:
// If collapsing an item, mark it as not new
if (!isExpanded.boolValue && self.isNewValue) {
self.isNew = @NO;
[self.parent setNumberOfNewItems:nil]; // Triggers KVO for button binding
}
... that 所做的是使用父级的空 setNumberOfNewItems setter 来强制按钮绑定调用 getter。因此,每次将项目标记为非新时,都会枚举整个对多 children 关系。我认为这可以改进,但我还没有尝试过。
我利用了一个项目在我的代码中仅在一个位置被标记为非新的事实。如果您在子项中有多项重置或设置 isNew,您可以在 childItem 类中覆盖 setIsNew 以调用 self.parent setNumberOfNewItems:nil。
这里的诀窍是让父级将自己添加为所有子级的 isNew 键路径的 KVO 观察者将是一个可怕的痛苦。所以我想避免这种情况。如果您只是让子级调用父级中的空设置器,则父级可以拥有计算,并且绑定使用之外没有 KVO。
看起来像这样: