Предположим, что в вашем NSOutlineView у вас есть childrenKeyPath из «children», а у дочерних элементов есть логический атрибут isNew. Что вам нужно, так это красивый numberOfNewItems пузырек в виде ячеек для одного класса объектов. Я назову это родительским объектом.
Если вам просто нужно количество объектов в childrenKeyPath, черт возьми, это еще проще, но я проведу вас через более сложный случай отслеживания определенного логического свойства у дочерних элементов, потому что этот шаблон достаточно легко упростить.
В виде ячейки таблицы для родительского объекта добавьте утопленную кнопку с заголовком, привязанным к objectValue.numberOfNewItems, и скрытым, привязанным к objectValue.NumberOfNewItems с преобразователем значений NSNegateBoolean. Если вам просто нужно количество дочерних элементов, переключите эти пути на objectValue.children.count, и все готово. Если вы хотите отслеживать такое свойство, как isNew, давайте продолжим ...
В родительском классе объекта есть этот код:
- (NSNumber*) numberOfNewItems
{
// Collection operator on boolean returns total number of new children
return [self valueForKeyPath:@"[email protected]"];
}
// 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];
}
Это вызывает пересчет numberOfNewItems каждый раз, когда значение objectValue ячейки таблицы получает новый дочерний элемент, добавляемый или удаляемый из отношения children ко многим.
В классе 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
}
... и что это делает, так это использование родительского пустого установщика setNumberOfNewItems, чтобы заставить привязку кнопки вызывать геттер. Таким образом, отношение «ко многим children» перечисляется каждый раз, когда элемент помечается как «не новый». Я предполагал, что это можно улучшить, но я еще не играл с этим.
Я воспользовался тем, что элемент помечен как не новый только в одном месте в моем коде. Если у вас есть несколько вещей, которые сбрасываются или устанавливаются isNew в дочернем элементе, вы можете переопределить setIsNew в классе childItem, чтобы вместо этого вызвать self.parent setNumberOfNewItems:nil.
Хитрость здесь в том, что добавление родителя в качестве наблюдателя KVO для ключевого пути isNew для всех дочерних элементов было бы ужасной болью. Так что я хотел этого избежать. Если у вас просто есть дочерние элементы, вызывающие пустой сеттер в родительском элементе, родитель может владеть вычислением, и нет KVO за пределами того, что используют привязки.
Выглядит так:

person
stevesliva
schedule
28.06.2014