NSTableView (View Based ) の初歩的実装

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/637ab8b6-5319-0e6a-c1a6-2e862913a26a.png)

# GitHub
- https://github.com/pommdau/tableView_ViewBased_01
    - 8d8e64516514f5cec6d17903fd05efa1642bcfcd

# 実装手順
- 今回はストーリーボード未使用。
- TableViewの処理は後述のNSObjectControllerのクラスで行う。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/e5cb5925-0898-34bb-227d-310442bbe267.png)

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/de1ddf3f-82b0-cc75-8519-7c14e4d3c196.png)

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/60326407-410d-fcd6-b906-53149a48d170.png)

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/cd2fc489-bca8-c5d7-5410-07cff411e85a.png)

- identifierの設定

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/1016348e-a837-eb8c-2716-bbf7ec6b14d2.png)

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

``` ObjectiveC
//  AppDelegate.h
//  TableView_ViewBased

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (readwrite,nonatomic) NSMutableArray* tableData;
@end
```

- `AppDelegate.m`にinitを追加、テーブルに表示するデータを初期化する

``` ObjectiveC
- (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をバインディング。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/198225/9457d303-d1be-995e-41ed-88d9899fe202.png)

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

``` ObjectiveC
#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
```

## 参考サイト
- [ビュー・ベースのテーブルビュー　基本のき(1)](http://saokkk.seesaa.net/article/433595368.html)
- [ビュー・ベースのテーブルビュー　基本のき(2)
](http://saokkk.seesaa.net/article/433645716.html)
- [AppDelegateを取得する](http://atmarkplant.com/appdelegate/)

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