NSOutlineView reloadItem: не действует

Я пытаюсь высвободить некоторую нагрузку на основанную на представлении NSOutlineView, для которой я изменил одно свойство элемента и которое я изначально перезагрузил, просто используя [myOutlineView reloadData].

Я пробовал [myOutlineView reloadItem: myOutlineViewItem], но он никогда не вызывает - (NSView *)outlineView:(NSOutlineView *)ov viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item, и, следовательно, данные не обновляются.

-(void)reloadOutlineViewObject
{
    //[myOutlineView reloadData];   //Reload data just fines but is ressource-hungry
    NSLog(@"%d",[myOutlineView rowForItem:myOutlineViewItem]; //Making sure my object is an item of the outlineView, which it is !
    [myOutlineView reloadItem:myOutlineViewItem];   
}

Я что-то пропустил?

UPDATE

Как указано в комментариях, мой outlineView основан на просмотре.

ОБНОВЛЕНИЕ 2

Попробовав некоторые вещи, я понял, что объект, который я перезагружаю, является объектом второго уровня (дерево объектов cf) и работает reloadItem:firstLevelObject reloadChildren:YES.

Возможно ли, что мы можем только вызвать reloadItem: на объекте первого уровня? Это было бы очень неэффективно в моем случае (у меня есть только один элемент уровня и много второго уровня)!

nil ->firstLevelA ->secondLevel1
                  ->secondLevel2
    ->firstLevelB ->secondLevel3
                  ->secondLevel4

Попробуем подклассифицировать NSOutlineView и переписать reloadItem: в среднем.

ОБНОВЛЕНИЕ 3

Я взглянул на NSOutlineView в Cocotron, чтобы начать, и почувствовал, что код, который мне нужен, чтобы перезаписать reloadItem, будет очень тяжелым. Кто-нибудь, чтобы подтвердить?

Ответы

Ответ 1

Я столкнулся с этой же проблемой с представлением на основе представления, где вызов -reloadItem: кажется просто ничего не делает. Это определенно кажется большой ошибкой, хотя в документации явно не сказано, что reloadItem будет повторно запрашивать представления для этой строки.

Мое обходное решение состояло в том, чтобы вместо этого вызвать NSTableView -reloadDataForRowIndexes:columnIndexes:, который, как представляется, работает должным образом, вызывая вызов метода делегата -outlineView:viewForTableColumn:item: только для этого элемента. Вы можете получить строку, которую нужно перезагрузить, вызывая -rowForItem: и передавая элемент, который вы хотите перезагрузить.

Ответ 2

Это действительно не ошибка - это было то, что я явно разработал. Я думал, что reloadItem (и т.д.) Должен просто перезагрузить свойства элемента контура, а не ячейку таблицы в этом элементе, поскольку он не несет достаточно конкретной информации о том, что нужно перезагрузить (например, какую конкретную ячейку вы можете захотеть перезагрузить). Я хотел, чтобы люди использовали reloadDataForRowIndexes: columnIndexes: перезагрузить определенную ячейку tableview view; мы обычно не предоставляем методы обложки, когда базовый класс может легко сделать то же самое с несколькими строками кода.

Однако, сказав это, я знаю, что несколько людей смущены этим, и большинство людей ожидают, что он также перезагрузит ячейку.

Пожалуйста, зарегистрируйте ошибку, требующую от Apple изменения.

спасибо, -corbin

Ответ 3

Apple, похоже, "исправила" его.

WWDC 2016, презентация 203 "Что нового в Cocoa" в 30:35 на видео:

"NSOutlineView

  • Перезапускает представления ячеек, связанные с "элементом", когда reloadItem() называется "

Ответ 4

reloadItem: работает только на macOS 10.12.

Из примечаний к выпуску: https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKit/

NSOutlineView теперь перезагружает представления ячеек, связанных с элементом когда вызывается [outlineView reloadItem:]. Метод просто вызывает [outlineView reloadDataForRowIndexes: columnIndexes:], передающий определенную строку, которая должна быть перезагружена, и все столбцы. Для совместимости, это будет работать только для приложений, которые связывают 10.12 SDK.

Итак, если вы хотите перезагрузить строку на более ранних системах, вы должны использовать -reloadDataForRowIndexes:columnIndexes:. Что-то вроде этого:

let index = self.outlineView.row(forItem: appClass)
let hackinIndex = IndexSet(integer: index)

let cols = IndexSet(integer: 5) //you need to provide columns here you want to reload.
self.outlineView.reloadData(forRowIndexes: hackinIndex, columnIndexes: cols)