17

我正在尝试释放基于视图的压力,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];   
}

我在这里错过了什么吗?

更新

正如评论中所指出的,我的 outlineView 是基于视图的。

更新 2

尝试一些东西让我意识到我正在重新加载的对象是一个二级对象(cf 对象树)并且调用reloadItem:firstLevelObject reloadChildren:YES确实有效。

是否有可能我们只能在第一级对象上调用 reloadItem: ?在我的情况下,这将是非常低效的(我只有一个二级项目和大量二级项目)!

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

将尝试继承 NSOutlineView 并同时重写reloadItem:

更新 3

我查看了 Cocotron 中的 NSOutlineView以开始使用,并觉得我需要编写的覆盖 reloadItem 的代码会很繁重。有人确认吗?

4

4 回答 4

16

我在基于视图的大纲视图中遇到了同样的问题,其中调用-reloadItem:似乎没有做任何事情。这绝对看起来像是一个大错误,尽管文档没有明确说明reloadItem会重新获取该行的视图。

我的解决方法是改为调用NSTableView's -reloadDataForRowIndexes:columnIndexes:,这似乎按预期工作,触发了-outlineView:viewForTableColumn:item:对该项目的委托方法的调用。您可以通过调用-rowForItem:并传入要重新加载的项目来获取需要重新加载的行。

于 2014-03-18T21:53:56.927 回答
10

这真的不是一个错误——这是我明确设计的。我的想法是 reloadItem (等)应该只重新加载大纲视图项目属性,而不是该项目的表格单元格,因为它没有携带关于重新加载内容的足够具体信息(例如您可能想要重新加载的特定单元格)。我原本打算让人们使用 reloadDataForRowIndexes:columnIndexes: 重新加载基于特定视图的 tableview 单元格;当基类只需几行代码即可轻松完成相同的事情时,我们通常不提供覆盖方法。

但是,话虽如此,我知道很多人对此感到困惑,并且大多数人都希望它也会重新加载单元格。

请记录一个错误,要求 Apple 更改此设置。

谢谢,-科尔宾

于 2016-03-28T14:24:27.203 回答
4

苹果似乎已经“修复”了它。

WWDC 2016,演示文稿 203“可可的新功能”,视频中的 30:35:

"NSOutlineView

  • 调用 reloadItem() 时重新加载与“项目”关联的单元格视图”
于 2016-06-16T19:28:44.290 回答
2

reloadItem:仅适用于 macOS 10.12。

来自发行说明: https ://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKit/

NSOutlineView 现在将在调用 [outlineView reloadItem:] 时重新加载与 'item' 关联的单元格视图。该方法只需调用 [outlineView reloadDataForRowIndexes:columnIndexes:] 传递要重新加载的特定行和所有列。为了兼容性,这仅适用于链接到 10.12 SDK 的应用程序。

因此,如果您想在早期系统上重新加载行,您应该使用-reloadDataForRowIndexes:columnIndexes:. 像这样的东西:

let index = outlineView.row(forItem: obj)
let rowIndex = IndexSet(integer: index)

let cols = IndexSet(0 ... outlineView.numberOfColumns) 

outlineView.reloadData(forRowIndexes: rowIndex, columnIndexes: cols)
于 2016-12-15T14:00:44.627 回答