【发布时间】:2019-11-19 10:19:12
【问题描述】:
我有一个基于视图的 NSOutlineView 和 dataSource/delegate 模型,而不是绑定到树控制器(我想控制插入/更新动画)。
我正在替换模型中的一个项目,并希望在大纲视图中更新该特定行,而无需调用 reloadData()。
我无法让它工作。要么项目根本不更新,要么项目的展开状态不更新。根据this,似乎在 NSOutlineView 内部进行了一些缓存,但即使有这些建议,我也无法让它工作。
我有什么:
(1)大纲视图表示一个文件夹结构
(2)首先有一个单一的文件:
(3) 然后用文件夹项替换文件:
// Model update
let oldFileItem = rootItem.children.first!
rootItem.children.remove(at: 0)
rootItem.children.append(Item(title: "Folder", children:[], isExpandable:true))
预期结果:
实际结果(reloadItem):
outlineView.reloadItem(oldFileItem) // I kept a reference
图标和标题已重新加载,但请注意缺少扩展三角形。
我可以理解 reloadItem() 在这种情况下可能不起作用,因为旧项目不再是数据模型的一部分。奇怪的是,项目的标题和图标更新了,但展开状态没有更新。
实际结果(reloadData(forRowIndexes:columnIndexes:):
outlineView.reloadData(forRowIndexes: IndexSet(integer:0), columnIndexes: IndexSet(integer:0))
没有任何影响。这是我期望的工作。
实际结果(删除/插入):
outlineView.removeItems(at: IndexSet(integer:0), inParent: rootItem, withAnimation: [])
outlineView.insertItems(at: IndexSet(integer:0), inParent: rootItem, withAnimation: [])
没有任何影响。
关于removeItems() 的文档说:“如果不扩展父级,该方法什么也不做。”并且 isExpanded 确实为根节点返回 false,尽管它的子节点是可见的。这是根节点的直接子项的特殊行为吗?我在这里错过了什么?
作为参考,我的数据模型:
class Item:NSObject {
var title:String
var children:[Item]
var isExpandable:Bool
init(title:String, children:[Item], isExpandable:Bool) {
self.title = title
self.children = children
self.isExpandable = isExpandable
}
}
【问题讨论】:
-
数据源和委托方法是否返回正确的值?
rootItem是否曾经从数据源方法返回?insertItems(at:inParent:withAnimation:)的文档说“父项:项目的父项,如果父项是根,则为 nil。”。 -
你说的太对了!事实上,我应该使用 nil 而不是 rootItem。通过该更改,将反映更新。谢谢!!随时将您的评论变成答案,我会接受。
标签: cocoa nsoutlineview