NSTableViewいろいろなセルを表示

NSTableViewのセルにテキスト以外のもの(NSButtonCell等)を表示させる方法はいつくかあります。

  1. IBで設定する
  2. NSTableColimnのsetDataCell:を使う
  3. NSTableColumnのdataCellForRow:をオーバーライドする
  4. NSTableViewのデリゲートメソッドを使う

等々。

今回の目的(何番煎じなのかわかりませんが)

  • NSTableViewにいろんなセルを表示してみる
  • 行によって違う種類のセルを表示する
  • 実用性は考えない


今回、
僕自身は使ったことの無いNSTableViewのデリゲートメソッドで実践してみたいと思います。
こちらがそのメソッド

- (NSCell *)tableView:(NSTableView *)tableView
 dataCellForTableColumn:(NSTableColumn *)tableColumn
 row:(NSInteger)row

リファレンスによると、
このメソッドの返り値(NSCell*)は
NSTableColumnのdataCellForRow:の変わりになるようです。
ということは、だんだんごちゃごちゃしてきて、
NSTableColumnのサブクラスを利用したくなったら、
そのまま転用可能ですね。



まぁ、なにはともあれ、コーディングです。
適当なので参考にならないと思います

/*========================================================================
 *	NSTableColumn の identifier
 *	IBにて設定
 *========================================================================*/
NSString * const kMCTextFieldColumnID    = @"MCTextColumn";
NSString * const kMCButtontColumnID = @"MCButtonColumn";
NSString * const kMCPopUpColumnID   = @"MCPopUpColumn";
NSString * const kMCSliderColumnID  = @"MCSliderColumn";
NSString * const kMCDynamicCellColumnID = @"MCDynamicColumn";


/*========================================================================
 *	行によってセルが変わる NSTableColumn のための
 *	セル識別番号
 *========================================================================*/
enum {
	MCLevelIndicatorCell = 0,
	MCSegmentedCell,
	MCTokenTextFieldCell,
	MCSecureTextFieldCell,
	MCImageButtonCell,
	MCStepperCell,
	MCImageCell,
};
NSInteger NumberOfMultipleCells = 7;


/*========================================================================
 *	行の高さ
 *========================================================================*/
CGFloat   HeightOfRow           = 30.0f;


/*========================================================================
 *	表示する行の数
 *	本来なら表示用データの数を使うべき
 *		例)[<NSArray> count] 等
 *========================================================================*/
NSInteger NumberOfTableRows     = 7;


#pragma mark -
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
	//  MCTableView_:表示させるNSTableView
	[MCTableView_ setDelegate:self];
	[MCTableView_ setDataSource:self];
}



#pragma mark -
#pragma mark tableViewDelegate
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
	/*========================================================================
	 *	行の高さを返します
	 *	ここで、うまく処理してあげれば、行によって高さを変えることが出来ます。
	 *========================================================================*/	
	return HeightOfRow;
}

#define CompareColumnID(ID) [[tableColumn identifier] isEqualToString:(ID)]
- (NSCell *)tableView:(NSTableView *)tableView
dataCellForTableColumn:(NSTableColumn *)tableColumn
				  row:(NSInteger)row
{
    if (CompareColumnID(kMCTextFieldColumnID))
	{
		/*========================================================================
		 *	NSTextFieldCell
		 *========================================================================*/
		NSTextFieldCell * txcell = [[[NSTextFieldCell alloc] init] autorelease];
		return txcell;
	}
    else if (CompareColumnID(kMCButtontColumnID))
	{
		/*========================================================================
		 *	NSButtonCell
		 *========================================================================*/
		NSButtonCell * btcell = [[[NSButtonCell alloc] init] autorelease];
		[btcell setButtonType:NSSwitchButton];
		[btcell setTitle:@"check"];
		return btcell;
	}
    else if (CompareColumnID(kMCPopUpColumnID))
	{
		/*========================================================================
		 *	NSPopUpButtonCell
		 *========================================================================*/
		NSPopUpButtonCell * popcell = [[[NSPopUpButtonCell alloc] init] autorelease];
		[popcell addItemsWithTitles:[NSArray arrayWithObjects:
									 @"pop",
									 @"up",
									 @"cell",
									 nil]];
		return popcell;
	}
    else if (CompareColumnID(kMCSliderColumnID))
	{
		/*========================================================================
		 *	NSSliderCell
		 *========================================================================*/
		NSSliderCell * slcell = [[[NSSliderCell alloc] init] autorelease];
		[slcell setMinValue:0];
		[slcell setMaxValue:100];
		//
		// setSliderType:(NSSliderType)sliderType
		//    (NSSliderType)
		//         NSLinearSlider   = 0
		//         NSCircularSlider = 1
		//
		[slcell setSliderType:row%2];
		return slcell;
	}
	else if (CompareColumnID(kMCDynamicCellColumnID)) {
		id mcell;
		switch (row%NumberOfMultipleCells) {
			case MCLevelIndicatorCell:
				/*========================================================================
				 *	NSLevelIndicatorCell
				 *========================================================================*/
				mcell = [[[NSLevelIndicatorCell alloc] init] autorelease];
				[mcell setMaxValue:NumberOfTableRows];
				break;
			case MCSegmentedCell:
				/*========================================================================
				 *	NSSegmentedCell
				 *========================================================================*/
				mcell = [[[NSSegmentedCell alloc] init] autorelease];
				[mcell setSegmentCount:3];
				[mcell segmentStyle];
				break;
			case MCTokenTextFieldCell:
				/*========================================================================
				 *	NSTokenTextFieldCell
				 *========================================================================*/
				mcell = [[[NSTokenFieldCell alloc] init] autorelease];
				break;
			case MCSecureTextFieldCell:
				/*========================================================================
				 *	NSSecureTextFieldCell
				 *========================================================================*/
				mcell = [[[NSSecureTextFieldCell alloc] init] autorelease];
				break;
			case MCImageButtonCell:
				/*========================================================================
				 *	NSButtonCell
				 *========================================================================*/
				mcell = [[[NSButtonCell alloc] init] autorelease];
				[mcell setImage:[NSImage imageNamed:NSImageNameRefreshTemplate]];
				[mcell setBezelStyle:NSTexturedRoundedBezelStyle];
				break;
			case MCStepperCell:
				/*========================================================================
				 *	NSStepperCell
				 *========================================================================*/
				mcell = [[[NSStepperCell alloc] init] autorelease];
				[mcell setMinValue:0];
				[mcell setMaxValue:100];
				break;
			case MCImageCell:
				/*========================================================================
				 *	NSImageCell
				 *========================================================================*/
				//NSImageCell * imgcell = [[[NSImageCell alloc] init] autorelease];
				mcell = [[[NSCell alloc] init] autorelease];
				[mcell setImage:[NSImage imageNamed:NSImageNameQuickLookTemplate]];
				break;
			default:
				break;
		}
		return mcell;
	}
	
	return nil;
}



#pragma mark -
#pragma mark tableViewDataSource
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
	return NumberOfTableRows;
}

- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
			row:(NSInteger)row
{
	id ret;
	
	if (CompareColumnID(kMCTextFieldColumnID))
	{
		/*========================================================================
		 *	NSTextField
		 *		NSString を返す
		 *========================================================================*/
		ret = [NSString stringWithFormat:@"text%d",row];
	}
    else if (CompareColumnID(kMCButtontColumnID))
	{
		/*========================================================================
		 *	NSButton
		 *		NSNumber を返す
		 *			NSButton のステイト状態
		 *========================================================================*/
		ret = [NSNumber numberWithBool:(BOOL)(row%2)];
	}
    else if (CompareColumnID(kMCPopUpColumnID))
	{
		/*========================================================================
		 *	NSPopUpButton
		 *		NSNumber を返す
		 *			ポップアップリストで選択されるインデックス
		 *========================================================================*/
		ret = [NSNumber numberWithInt:row%3];
	}
    else if (CompareColumnID(kMCSliderColumnID))
	{
		/*========================================================================
		 *	NSSlider
		 *		NSNumber を返す
		 *			NSSlider に設定したい数値
		 *========================================================================*/
		ret = [NSNumber numberWithFloat:((100.0f/NumberOfTableRows)*row)];
	}
	else if (CompareColumnID(kMCDynamicCellColumnID)) {
		switch (row%NumberOfMultipleCells) {
			case MCLevelIndicatorCell:
				/*========================================================================
				 *	NSLevelIndicator
				 *		NSNumber を返す
				 *			NSLevelIndicatorCell に設定したい数値
				 *========================================================================*/
				ret = [NSNumber numberWithInt:2];
				break;
			case MCSegmentedCell:
				/*========================================================================
				 *	NSSegmentedCell
				 *		NSNumber を返す
				 *			選択したいセグメントのインデックス
				 *========================================================================*/
				ret = [NSNumber numberWithInt:2];
				break;
			case MCTokenTextFieldCell:
				/*========================================================================
				 *	NSTokenField
				 *		NSString を返す
				 *========================================================================*/
				ret = @"token";
				break;
			case MCSecureTextFieldCell:
				/*========================================================================
				 *	NSSecureTextField
				 *		NSString を返す
				 *========================================================================*/
				ret = @"secure";
				break;
			case MCImageButtonCell:
				/*========================================================================
				 *	NSButtonCellに同じ
				 *========================================================================*/
				ret = [NSNumber numberWithBool:YES];
				break;
			case MCStepperCell:
				/*========================================================================
				 *	NSStepper
				 *		NSNumber を返す
				 *			NSStepper に設定したい数値
				 *========================================================================*/
				ret = [NSNumber numberWithInt:row];
				break;
			case MCImageCell:
			default:
				ret = nil;
				break;
		}
	}
	else
	{
		ret = nil;
	}
	
	return ret;
}