在没有NSTreeController的情况下,在模型更改时自动更新NSOutlineView

时间:2012-05-12 11:09:29

标签: objective-c cocoa key-value-observing nsoutlineview nstreecontroller

如果我将NSOutlineView从使用绑定和NSTreeController更改为拥有数据源和委托,如果我的模型树发生更改,我将如何自动更新NSOutlineView?我应该使用我的控制器观察树中每个节点的childNodes属性,并在发生更改时触发重新加载吗?或者还有另一种方式吗?

2 个答案:

答案 0 :(得分:1)

这是一种方式。另一种方法是模型在更改时发布通知并让控制器观察通知。

此外,模型通常不会自发地改变。通常,响应某些事件,在模型外部启动更改。控制器通常会这样做。因此,该控制器还可以激发对大纲视图的更新。 (可能有多个控制器,因此启动模型更改的控制器可能会通知窗口或视图控制器,它将负责更新大纲视图。)

答案 1 :(得分:0)

我在这里问了一个标记为重复的类似问题:Recommended Pattern for Observing Changes in Tree Structure [duplicate]

我想避免使用NSTreeController,因为这意味着您在更新时失去对动画的控制。

我已经设置了MVVM。我的模型是图形,我的视图模型是树。任何树节点和图节点之间存在一对一的关系。如上面的问题所详述,树节点和大纲视图之间显然存在多种关系。

所以,我决定......

视图模型树节点需要知道他们的子节点何时更新,因此我使用关联图节点的KVO来捕获添加或删除子节点的时间。

对于大纲视图更新,我确定了我在视图控制器上实现的模型视图委托。添加或删除子项时,视图模型中的每个树节点都可以在树根上调用委托方法。这对我来说是最清晰的方法,并且易于调试。我不想要在幕后发生一系列事情。

最终的大纲视图更新调用感觉非常简单:

func itemsInserted(atIndexes indexes: IndexSet, forParent parent: ECViewModelNode) {
        outlineView?.insertItems(at: indexes, inParent: parent, withAnimation: .slideDown)
    }

在table-cell-view级别,我直接绑定到图模型节点的细节。