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)