NSOutlineViewDelegate プロトコル

NSOutlineView 関連のプロトコルでは、DataSource の方は存在感があるが Delegate の影は薄い。

まあ、DataSource の方はないと表示すらできないわけだが…。

試しに

@interface OutlineviewManager : NSObject<NSOutlineViewDataSource>

@interface OutlineviewManager : NSObject<NSOutlineViewDataSource, NSOutlineViewDelegate>

としてもコンパイル自体はできる。

行選択時の機能

公式ページを見るに、行選択をした時のメソッドを供給しているようです。

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;

のメソッドは、公式の説明だと item が選択できるかどうかを定義するもののように紹介されていますが、おそらく機能も提供できます。
OutlineView に Person クラス(のインスタンス)を表示させているとき

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
Person *p = item;
NSLog(@"%@", p.name);

return YES;
}

を実装しておくと name プロパティの値(文字列)を表示してくれます。

 

NSOutlineView と item

多層構造のデータ表示の仕方がわからない、と言っていたが、試行錯誤の末、できた。

Person – Child – GChild という階層を持つデータがあったとき、適切に実装すると以下のように表示が可能だ。

ポイントは、 item をうまく使うこと。

具体的には

-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    if(item){
        if([item isKindOfClass:[Child class]] ){
            Child *c = item;
            return [c.gchildren count];
        }
        if([item isKindOfClass:[Person class]] ){
            NSLog(@"this item is Person");
            return [[item children] count];
        }
        return 0;
    }else{
        return [self.objects count];
    }
}

などとする。

直感的には item = 行(インスタンス1つ)という理解でいいと思う。
トップ階層(item が定義できない)は、self.objects count などとしているわけですね。

参考

・ここでの質疑応答

item という概念がわからないというある人の問題提起に対して林さんが

私の場合ですが、実データを入れるクラスとOutlineのアイテムを別々のクラスにして、アイテムの方のクラスのプロパティに実データのクラスのインスタンスを入れるように実装したことがあります。アウトラインに表示する時にものによってそれに対応するデータのクラスが異なっていたので、アウトラインビューのデータソースのアイテムは表示のためのものと割り切りました。

と応えている。

これは考えてみれば当たり前の話で、NSOutlineView からしてみれば、どんなデータが要素になるかわからない。
だから、そこら辺はコーダーの方で処理してくれよ、という話になる。

・YouTube の動画

動画は流れを掴むのにちょうどいい。

31:53 TableColumn の identifier の設定。
36:30 NSOutluneView と管理クラスの結び付け(datasource 経由

あたりは「百聞は一見にしかず」でしょう。

・OsiriX/Horos/HorliX における NSOutlineView

調査中。

・NSTreeView を使う

この記事で NSTreeView を使っていた。
手が空いたら試す。

・公式解説