reboot
ここ数ヶ月、IT とは別件の仕事に追われていたので、再起動。
期間が空いても C や Java の基本を忘れることはまずないが、開発環境の使い方なぞはよく忘れる。
というわけで『Xcode で GUI アプリ』再読。
あー、main.m ってあったなあとか、徐々に思い出していく。
しかし、AppDelegate に代表されるデリゲートパターンはクセ強いよね。いまだにしっくりきてない。
(続く)
babour
お久しぶりです。
所用でかなり放置。
ところで久々のファッションネタ。
冬のアウターは2年ほど前からモッズコート系にしていたのだが、気軽に着れるものではない。
悩みながら物色していたのだが、結局、babour (日本ではバブアーと呼ばれている)インターナショナルのパチモノ・・レプリカを購入した。
バブアー本物はメンテが面倒そうというのと現時点(2023 秋冬)では日本公式ではインターナショナルを取り扱っていないというのがその理由。
パチモノなら、オイル抜き・リプルーフも失敗を恐れずにできる(はず)。
なお、参考になった動画。
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
です。
