簡単にNSTableViewにソート機能をつける方法

Macアプリでは、iOSと違ってNSArrayControllerという便利なオブジェクトがあって、これに配列のデータを放り込んでNSTableViewに関連づけると、ソート機能を実装してくれるようです。テーブルのカラムヘッダをクリックするとそのカラムがソートされる、あれです。楽ですね〜。 今回、Macアプリでその便利なArray Controllerを使わずにテーブルを実装してみているのですが、ソートで困りました。ソート以外は、iOSのテーブルビューコントローラと同じような感じでdata sourceやdelegateメソッドを実装すればちゃんとデータが表に表示されて使えるのですが、ソートはデフォルトでは機能しないようです。かなり悩みましたが、よく考えると、そりゃそうですよね。どんなデータが入っているかも分からないのにソートのしようがないですよね…。 そうなると、カラムヘッダがクリックされるたびに自分でソートデータをソートさせて再表示するしかないのかと、その予想される作業量の多さに途方に暮れながらXcodeをいじっていたら、簡単にできる方法を見つけました!

ソート機能を追加する手順

1. データの準備

テーブルに表示するデータをキーパスが指定できるデータにします。

例えば、次のようなNSDicstionaryの配列です。

NSArray *tableArray = [NSArray arrayWithObjects:
                       [NSDictionary dictionaryWithObject:@"2011/01/01" forKey:@"start"],
                       [NSDictionary dictionaryWithObject:@"2011/01/02" forKey:@"start"],
                       [NSDictionary dictionaryWithObject:@"2011/01/03" forKey:@"start"],
                       [NSDictionary dictionaryWithObject:@"2011/01/04" forKey:@"start"],
                       [NSDictionary dictionaryWithObject:@"2011/01/05" forKey:@"start"],
                       nil];

CoreDataから取得したデータをそのまま配列にしてもできます。

2. カラムにソート属性を設置

Attributes InspectorでSort Keyにキーパス(CoreDataのデータ配列の場合はAttribute名)を指定します。(Selectorは、Sort Keyを入力すると自動的にcompare: がセットされます。) Xcodeの設定はこれだけです。

3. ソート変化時のdata sourceメソッドを実装

カラムヘッダがクリックされてソート順が変化した時に呼び出される次のメソッドを実装します。

- (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)oldDescriptors 
{ 
    //配列をテーブルビューが保持してるソート順でソート
    [self.dataArr sortUsingDescriptors:[self.tableView sortDescriptors]];

    //テーブルビューを再表示
    [self.tableView reloadData];
}

とっても簡単ですね! ところで、この記事を書いている時に、ことえりがこんな変換候補を出してくれましたが、もしかして10.7.3の新機能なのでしょうか(・・)?