サンプル
通常だとこんな感じ。
これを背景色とフォントを変えてみる。
NSTableViewの構成
NSTableView のヘッダ描画は NSTableHeaderView が管理しているが、実際の描画はこの NSTableHeaderView が NSTableHeaderCell に委託している。そんな構成なので NSTableHeaderCell は NStableHeaderView から得られると思いきやそうではなく、NSTableColumn が参照を持っている。図解するとこんな関係。
この関係からヘッダをカスタマイズする場合は次の手順を踏めば良いことがわかる。
- NSTableView から NSTableColumn を取得
- NSTableColumn から NSTableHeaderCell を取得
- NSTableHeaderCell の draw系メソッドをオーバーライド
NSTableHeaderCell は NSCell のサブクラスなので通常のセルと同じように標準で用意されている描画系メソッドをオーラーライドすれば表示内容をカスタマイズできる。主な描画系メソッドは2つ:
-drawInteriorWithFrame:inView: -drawWithFrame:inView:前者はセルの内側のエリアのみ(枠部分を除く)。後者はセルの前エリアの描画。標準の実装では -drawWithFrame:inView: の中で、背景と枠を描画した後 -drawInteriorWithFrame:inView: を呼び出しているようだ。前者でオーバーライドした場合はこんな感じになる。
今回は後者のメソッドをオーバーライドする。
実装
今回は NSTableView と NSTableHeaderCell のサブクラスを用意した。まずは NSTableView のサブクラス。
@interface CustomTableView : NSTableView { } @end
- (void)_setupHeaderCell { for (NSTableColumn* column in [self tableColumns]) { NSTableHeaderCell* cell = [column headerCell]; CustomHeaderCell* newCell = [[CustomHeaderCell alloc] init]; [newCell setAttributedStringValue:[cell attributedStringValue]]; [column setHeaderCell:newCell]; [newCell release]; } } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self _setupHeaderCell]; } return self; }Nib から生成される初期化タイミングで NSTableHeaderCell を CustomHeaderCell に置き換えている。この時、既存の NSTableHeaderCell の情報(attributedStringValue)を持ち越している。こうすると Interface Builder で設定したヘッダの文字列や位置決め(中央寄せ)などの情報を反映させることができる。
次は NStableHeaderCell のサブクラス。こんな感じ。
@interface CustomHeaderCell : NSTableHeaderCell { } @end
@implementation CustomHeaderCell - (void)_drawInRect:(NSRect)rect { // 背景描画 [[NSColor orangeColor] set]; NSRectFill(rect); // 文字描画 NSMutableAttributedString* attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedStringValue]]; NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSColor whiteColor], NSForegroundColorAttributeName, [NSFont boldSystemFontOfSize:14.0], NSFontAttributeName, nil]; [attributedString addAttributes:attributes range:NSMakeRange(0, [attributedString length])]; rect.origin.y += 3; // Y位置を調整(中央寄せになるように) [attributedString drawInRect:rect]; } #pragma mark - #pragma mark Overridden methods (NSCell) - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { [self _drawInRect:cellFrame]; } @end-drawWithFrame:inView: をオーバーライドし、背景と文字描画を行っている。ここでは NSAttributedString のフォントと文字色の属性を変更している。ちなみにデフォルトのフォントは「Default Helvetica 12-point」。なお NSAttributedString で setAttributes:range: を使うと既存の属性も含めた置き換えになるので注意。
ソースコード
GitHub からどうぞ。
CustomHeaderSample at 2011-01-24 from xcatsan/MacOSX-Sample-Code - GitHub
Responses
Leave a Response