(前回)Cocoaの日々: NSTableView にカスタムビューを表示する(2) ひな形作成〜Cocoa Bindings
今回は NSCell のサブクラスを作り、それを NSTableView へ表示してみよう。
ビュー
新規にウィンドウを用意しそこへ NSTableView を貼付ける。前回のものは比較の為に残しておく。
NSTableView の delegate として TableViewController を指定しておく。
カスタムセル
NSCell のサブクラスを用意する。
CustomCell.h
@interface CustomCell : NSCell {
}
@end
試しに drawWithFrame:inView: をオーバーライドして、緑色で塗りつぶすコードを書いてみた。
CustomCell.m
@implementation CustomCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[[NSColor greenColor] set];
NSRectFill(cellFrame);
}
@end
NSTableViewDelegate
NSTableViewDelegate のうち -tableView:dataCellForTableColumn:row: を実装した。
TableViewController.m
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSLog(@"tableView: %@", tableView);
NSLog(@" tableColumn: %@", tableColumn);
NSLog(@" row: %d", row);
CustomCell* cell = [[[CustomCell alloc] init] autorelease];
return cell;
}
呼び出し状況がわかるように NSLog を入れておいた。
実行
出た。
デバッガコンソールを見ていると -[NSTableViewDelegate tableView:dataCellForTableColumn:row:] は頻繁に呼び出されている。
NSTableView をスクロールするとこれから表示されようとする行(row)で呼び出されるし、マウスカーソルを上に載せても呼び出される。また tableColumn が null だった。
考察
今回は -[NSTableViewDelegate tableView:dataCellForTableColumn:row:] の呼び出し毎に NSCell を生成して返していた。何度も呼び出される事を考えると使い捨てではなく、あらかじめ NSCellをプールしておいて再利用する方が良いかもしれない。そういえば iPhone の UITableViewCell は再利用を前提とした作りになっていたっけ。ただ UITableViewCell は UIView のサブクラスなので、NSViewよりも軽い NSCellの場合はそこまで考えなくてもよいかもしれない。
なお NSCell のサブクラス化については Mac Dev Center に指針がある。
Mac Dev Center: Control and Cell Programming Topics for Cocoa: Subclassing NSCell必要なら初期化メソッド(-initImageCell など)のオーバーライドすることやその他Target-Action、マウストッキング、描画を行う際にオーバライドすべきメソッドが紹介されている。また最後に copyWithZone: についての説明もあった。
If the subclass contains instance variables that hold pointers to objects, consider overridingcopyWithZone:
to duplicate the objects. The default version copies only pointers to the objects.
NSCell は複製されて使われることが多いということか。今後の実装で copyWithZone: を考慮することは覚えておこう。そういえば ADCのサンプル SourceView でもカスタムセルは copyWithZone: を実装していたっけ。
ソースコード
github からどうぞ。
CustomCell at 20091126 from xcatsan's SampleCode - GitHub
参考
NSTableView with custom cells - Stack Overflow