4

NSTreeController とバインディングを使用して、ビューベースの NSOutlineView をモデルに接続しようとしています。

私のモデルは、メインの Node クラス (およびそのサブクラス) で構成されています。すべてのノードは、0 個以上の子を持つことができます。パフォーマンス上の理由から、(Node オブジェクトの) C 配列に子を格納しています。childrenKeyPathcountKeyPathおよびleafKeyPathNSTreeController のプロパティを定義し、それらを Node クラスに実装しました。

- (NSArray *)childNodes {
return [NSArray arrayWithObjects:children_ count:childCount_];
}

- (BOOL)nodeIsLeaf {
    return childCount_ < 1;
}

- (NSUInteger)childCount {
    return childCount_;
}

新しい子を追加するときは、C 配列に挿入する[self willChangeValueForKey:@"childNodes"]前後に呼び出します。[self didChangeValueForKey:@"childNodes"]

ドキュメントに記載されているようにバインディングをセットアップしました。(NSTreeController のコンテンツ オブジェクトをルート ノードにバインドしました。NSOutlineView のコンテンツを NSTreeController の ArrangeObjects にバインドしました。また、NSTextField を NSTableViewCell の objectValue.name プロパティにバインドしました)

初期構成 (ルート オブジェクトとその子) は、アプリの実行時に正常に読み込まれます。ルート オブジェクトに新しい子を追加することもできます。

ただし、子がまだない (開示三角形がない) ノード (ルートを除く)に新しい子を追加しようとすると、NSOutlineView は更新されません (まだ三角形はありません)。新しいノードがモデルに正しく挿入され、will/didChangeValue メッセージが送信されますが、NSTreeController は新しい子配列を調べません。この場合、上記の 3 つの keyPath 関数をログに記録しても、何も出力されません。

親を閉じて再度展開すると、ノードがリロードされ、三角形が表示され、ノードを展開して追加したばかりの新しいノードを表示できます。children 配列を変更するときに KVO メッセージを送信したにもかかわらず、NSTreeController が変更を調べないのはなぜですか?

4

1 に答える 1

1

OKこれでできます:

/* item is the item which has just had new children added */
[_outlineView reloadItem:[_outlineView parentForItem:item] reloadChildren:YES];

効率が悪いかもしれませんし、Mountain Lion で修正されるかもしれませんが、これでうまくいきました。これを行うのに必要な回数を、アイテムが 0 -> 1 人の子 (およびその逆) の場合に制限できます。

于 2012-12-06T21:59:20.027 に答える