NSOutlineViewDelegate プロトコル

NSOutlineView 関連のプロトコルでは、DataSource の方は存在感があるが Delegate の影は薄い。

まあ、DataSource の方はないと表示すらできないわけだが…。

試しに

@interface OutlineviewManager : NSObject<NSOutlineViewDataSource>

@interface OutlineviewManager : NSObject<NSOutlineViewDataSource, NSOutlineViewDelegate>

としてもコンパイル自体はできる。

行選択時の機能

公式ページを見るに、行選択をした時のメソッドを供給しているようです。

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;

のメソッドは、公式の説明だと item が選択できるかどうかを定義するもののように紹介されていますが、おそらく機能も提供できます。
OutlineView に Person クラス(のインスタンス)を表示させているとき

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
Person *p = item;
NSLog(@"%@", p.name);

return YES;
}

を実装しておくと name プロパティの値(文字列)を表示してくれます。

 

cocoa プログラミング

今まで延々 GUI なしの Objective-C の記事書いてきたが、ここらで GUI つまり cocoa の話もちらほら。

Q&A 形式で。

Q Xcode 上で GUI 部品をどう出せばいいかわからない。

A 右上の + ボタンを押下する。

すると検索画面が出現するので、検索窓から button だの view だの打ち込んでパーツ選ぶ。

なお、View 関係で View 自体の大きさをウィンドウのリサイズに追従させたいときは、Autoresize 使う。

 

(続く)

addsubview するときの view のお手軽な作成方法

文法ラウンドやメソッド暗記モードを経て、cocoa でアプリっぽいものを作成する機会が多くなったが、全然知られていない方法を一つ。

みんな大好き NSView だが、子供の view を作成して親 view に addsubview したいというときがしばしばある。

しかし、具体的な方法論がほとんど知られていない(笑)。

ワイは試行錯誤(といってもさほど時間はかからなかったが)の結果、以下のようにしている。

Xcode の + で UI パーツのライブラリを呼び出すダイアログを呼び出して、custom view をチョイス。

ここがキモだと思うのだが、これを親ビューが所属する Controller Scene に置く

すると上図のように Xcode 上でもしっかりと操作可能な形で配置される。

iOS 関係はわからんが、MacOS でこんな図は見たことがない。

追加した view を ChildView、元々あった view を ParentView とすると、ViewController の viewdidload あたりに

    _childview = [[ChildView alloc] initWithFrame:_parentview.frame];
    [_parentview addSubview:_childview];

としておくと、しっかりこのビューが生成される。

かなり便利な方法だと思うんだが、全然知られてないよね。

NSView の再描画

ところで MacOS の描画関係は Metal から入ったワイは、NSView は自動で再描画してくれるものだと思い込んでいたが、違うらしい。setNeedsDisplay メソッドで明示する。

 

Core Plot

これも今すぐどうこうという話ではないのだが、Core Plot という iOS/MacOS のグラフ・チャートライブラリを見つけたのでメモ。

公式リポジトリはこちら

arm Mac で使いたければ、release-2.4 のブランチを使う。

git clone -b release-2.4  git@github.com:core-plot/core-plot core-plot24

で落として、framework フォルダ内の .xocdeproj を Xcode で起動。

シェルスクリプトに不具合があるようだが、所定のファイルはできているようなので、この状態で本体自体をビルド。

CorePlot.framework が生成されるので、これを使いたいプロジェクトに取り込んで使用する。

この記事のサンプルを MacOS でビルド。

できてますね。
ソースコードは若干修正して以下のようになる。

#import <Cocoa/Cocoa.h>
#import <CorePlot/CorePlot.h>

@interface ViewController : NSViewController<CPTPieChartDataSource,CPTPieChartDelegate>

@property (readwrite, nonatomic) NSMutableArray *pieChartData;

@end

#import "ViewController.h"

@implementation ViewController

@synthesize pieChartData;

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // ホスティングビューを生成します。
    CPTGraphHostingView *hostingView = [[CPTGraphHostingView alloc]
                                        initWithFrame:CGRectMake(0, 0, 320, 320)];
    
    // グラフを生成します。
    CPTXYGraph *graph = [[CPTXYGraph alloc] initWithFrame:hostingView.bounds];
    hostingView.hostedGraph = graph;
    
    // 今回は円グラフなので、グラフの軸は使用しません。
    graph.axisSet = nil;
    
    // 円グラフのインスタンスを生成します。
    CPTPieChart *pieChart = [[CPTPieChart alloc] init];
    
    // 円グラフの半径を設定します。
    pieChart.pieRadius = 80.0;
    
    // データソースを設定します。
    pieChart.dataSource = self;
    
    // デリゲートを設定します。
    pieChart.delegate = self;
    
    // グラフに円グラフを追加します。
    [graph addPlot:pieChart];
    
    // グラフに表示するデータを生成します。
    self.pieChartData = [NSMutableArray arrayWithObjects:
                         [NSNumber numberWithDouble:40.0],
                         [NSNumber numberWithDouble:30.0],
                         [NSNumber numberWithDouble:20.0],
                         [NSNumber numberWithDouble:10.0],
                         nil];
    
    // 画面にホスティングビューを追加します。
    [self.view addSubview:hostingView];
}




// グラフに使用するデータの数を返すように実装します。
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    return [self.pieChartData count];
}

// グラフに使用するデータの値を返すように実装します。
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    return [self.pieChartData objectAtIndex:index];
}
@end

です。

 

NSSplitView

今すぐどうこうというわけではないが、NSSplitView を使えるとアプリのウィンドウの表現が豊かになりそうなので、ちょっと調べる。

ネット上で使えそうなリソースは・・・

How to Use NSSplitView in a macOS app

まあ、良い記事ではあると思うけど、ちょっと応用的でしょうか。

動画もあったが、現代的ではない。

いつもの通り、公式ページもチェック。

 

結局、自分で手を動かしてまあまあ使えるようになった。

上半分は Metal の View で下半分が NSView を Core Graphics で描画したものです。
NSSplitVewDelegate プロトコルを適用するところで、おかしな挙動するんじゃないかと思ってましたが、そんなことはなく。結果オーライということで。

静止画だと伝わらないですが、ディバイダで上下の比率を変えることができます。

今回はちょっと楽して ViewController に NSSplitVewDelegate プロトコルを適用してます。