NSTableView (View Based ) の初歩的実装


概要

  • NSTableViewにはCell BaseとView Baseの二種類があり、今回は後者の実装。
  • 下記の通り2列のシンプルな実装を行う。
  • 簡単な実装例が見つからずかなり苦労した。NSArrayControllerを使っているものはあるのだが。ヒレガス本はEntityとか使ってるし。
  • UITableViewやcellBaseのほうがまだ分かりやすいなあという印象

GitHub

実装手順

  • 今回はストーリーボード未使用。
  • TableViewの処理は後述のNSObjectControllerのクラスで行う。

  • NSObjectControllerクラスの「TableController」の作成。

  • Objectを追加し、クラスにTableControllerを設定

  • TableViewの追加とバインディング

  • identifierの設定

  • 今回TableViewに表示するデータはAppDelegate.h/mが所有する。
  • AppDelegate.hで変数宣言。
//  AppDelegate.h
//  TableView_ViewBased

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (readwrite,nonatomic) NSMutableArray* tableData;
@end
  • AppDelegate.mにinitを追加、テーブルに表示するデータを初期化する
- (id)init{
    self = [super init];
    if (self) {
        //テーブル表示データを初期化
        _tableData = [NSMutableArray array];
        [_tableData addObject: @{
                                 @"name" : @"ピカチュウ",
                                 @"type" : @"でんき"
                                 }];
        [_tableData addObject: @{
                                 @"name" : @"ゼニガメ",
                                 @"type" : @"みず"
                                 }];
        [_tableData addObject: @{
                                 @"name" : @"ヒトカゲ",
                                 @"type" : @"みず"
                                 }];
        [_tableData addObject: @{
                                 @"name" : @"フシギダネ",
                                 @"type" : @"くさ"
                                 }];
    }
    return self;
}
  • tableController.hにtableViewをバインディング。

  • TableController.mにTableView表示用に必要な関数を書く。
  • AppDelegateからデータを引っ張るのでimportを忘れずに。
#import "TableController.h"
#import "AppDelegate.h"

@implementation TableController

#pragma mark - NSTableView data source

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
    AppDelegate *appD = (AppDelegate*)[[NSApplication sharedApplication]delegate];
    return appD.tableData.count;
}

// 使い方はセル・ベースのtableView:objectValueForTableColumn:row:とほとんど同じ。
// コラムをidentifierで特定してデータ・ソース配列の中のrowインデクスと同じインデクスの値を返してやる。
// ビュー・ベースの場合はその値を当てがったセル・ビューを返すというだけだ。

- (NSView *)tableView:(NSTableView *)tableView
   viewForTableColumn:(NSTableColumn *)tableColumn
                  row:(NSInteger)row{
    AppDelegate     *appD           = (AppDelegate*)[[NSApplication sharedApplication]delegate];
    NSString        *identifier     = tableColumn.identifier;
    NSDictionary    *data           = [appD.tableData objectAtIndex:row];
    NSTableCellView *cellView       = [tableView makeViewWithIdentifier:identifier owner:self];
    cellView.textField.stringValue  = [data objectForKey:identifier];
    return cellView;
}
@end

参考サイト

これですべてのクラスから参照できます。お手軽ですね。加えて、アプリが起動している間、AppDelegateインスタンスは、かならず解放されずに保持される保証があるという点もあります。