XCode を使用せずに Cocoa アプリケーションをつくる
Cocoa を使ってアプリケーションを開発する場合,XCode の Interface Builder を利用するのが一般的かと思います.しかし,管理や配布の都合,アプリケーションの規模によっては,オブジェクトコード内に UI 情報を記述したい場合があります.本記事では,コンポーネントの種類やレイアウトをソース中に記述し,XCode を使用せずにアプリケーションを作成します.
Keywords: Cocoa, gcc, without XCode
Cocoa は,基礎となる技術に Model-View-Controller (MVC) アーキテクチャを用いており,開発者が MVC に従ってアプリケーションを設計することを想定しています.MVC は,ユーザーインターフェースをもつアプリケーションを,Model (データ),View (表示),Controller (処理) の 3 つの機能に分離し設計,実装する手法です.View 要素とは,Window 上に表示される Button や TextBox などであり,ユーザーからの入力を Model や Controller に伝えたり,アプリケーションの内部状態をユーザーに示す役割を持ちます.一方,Model や Controller は,ユーザー入力を処理したり,処理によって生じた内部状態の変化を View に通知します.
Cocoa における MVC では,Controller に Mediator デザインパターンを適用することで,View と Controller,Controller と Model の 2 つの結合に分離する,よりシンプルな構造となります.本記事では,ウィンドウに UI コンポーネントを配置して View を決定し,View と Controller を関連付ける方法を説明します.
以下にサンプルコードを示します.
1. UI コンポーネントの追加
Cocoa における描画要素は NSView クラスにより抽象化されており,Window の View 階層に追加されることで表示されます.NSWindow は View 階層の最上位となる NSView インスタンスを管理しており,このインスタンスは content view と呼ばれます.content view は,NSWindow の contentView メソッドを通じてアクセスすることができます.
コントロールの配置に Auto Layout システムを使用することで,ユーザーの操作による Window サイズの変化が生じても,View の自動的な配置調整が可能になります.View の配置を記述するには Constraint (拘束) を利用します.拘束内容は,NSLayoutConstraint インスタンスの初期化時に,constraintWithVisualFormat メソッド,または constraintWithItem メソッドにて記述されます.
2. Controller との関連付け
View と Controller 間でメッセージのやり取りを行うには,Target-Action 機構を利用します.Action とは View の内,特にボタンなどの UI コンポーネントがユーザーの操作を受けて発するメッセージのことです.実装上はコールバックやデリゲートに近く,特定の操作を受けた際に呼び出されるメソッドを登録する形になります.Target は Action を受信するオブジェクトのことで,登録したインスタンスのメソッドが Action の発信時に呼び出されます.
本記事では,Controller を次にように定義しました.
最後に以下のコマンドでビルドします.

Keywords: Cocoa, gcc, without XCode
Cocoa は,基礎となる技術に Model-View-Controller (MVC) アーキテクチャを用いており,開発者が MVC に従ってアプリケーションを設計することを想定しています.MVC は,ユーザーインターフェースをもつアプリケーションを,Model (データ),View (表示),Controller (処理) の 3 つの機能に分離し設計,実装する手法です.View 要素とは,Window 上に表示される Button や TextBox などであり,ユーザーからの入力を Model や Controller に伝えたり,アプリケーションの内部状態をユーザーに示す役割を持ちます.一方,Model や Controller は,ユーザー入力を処理したり,処理によって生じた内部状態の変化を View に通知します.
Cocoa における MVC では,Controller に Mediator デザインパターンを適用することで,View と Controller,Controller と Model の 2 つの結合に分離する,よりシンプルな構造となります.本記事では,ウィンドウに UI コンポーネントを配置して View を決定し,View と Controller を関連付ける方法を説明します.
以下にサンプルコードを示します.
#import <Cocoa/Cocoa.h>(本サンプルコードを書くにあたり,こちらの記事を参考にしました.)
@interface Controller : NSObject
- (void) hello:(id)sender;
@end
@implementation Controller
- (void) hello:(id)sender
{
NSLog(@"Hello World");
}
@end
int main()
{
[NSAutoreleasePool new];
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
id menubar = [[NSMenu new] autorelease];
id rootmenu = [[NSMenuItem new] autorelease];
[menubar addItem:rootmenu];
id appmenu = [[NSMenu new] autorelease];
id quitmenu = [[[NSMenuItem alloc]
initWithTitle:@"Quit"
action:@selector(terminate:)
keyEquivalent:@"q"] autorelease];
[appmenu addItem:quitmenu];
[rootmenu setSubmenu:appmenu];
[NSApp setMainMenu:menubar];
id window = [[[NSWindow alloc]
initWithContentRect:NSMakeRect(0,0,200,200)
styleMask:NSTitledWindowMask
backing:NSBackingStoreBuffered
defer:NO] autorelease];
id superview = [window contentView];
id button = [[[NSButton alloc]
initWithFrame:NSZeroRect] autorelease];
[button setTitle:@"Hello World"];
[button setBordered:YES];
[button setBezelStyle:NSRoundedBezelStyle];
[button setTranslatesAutoresizingMaskIntoConstraints:NO];
[superview addSubview:button];
id h_const = [[NSLayoutConstraint
constraintWithItem:superview
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:button
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0] autorelease];
id v_const = [[NSLayoutConstraint
constraintWithItem:superview
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:button
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0] autorelease];
[superview addConstraint:h_const];
[superview addConstraint:v_const];
[button setTarget:[[Controller new] autorelease]];
[button setAction:@selector(hello:)];
[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
[window setTitle:[[NSProcessInfo processInfo] processName]];
[window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
[NSApp run];
return 0;
}
1. UI コンポーネントの追加
Cocoa における描画要素は NSView クラスにより抽象化されており,Window の View 階層に追加されることで表示されます.NSWindow は View 階層の最上位となる NSView インスタンスを管理しており,このインスタンスは content view と呼ばれます.content view は,NSWindow の contentView メソッドを通じてアクセスすることができます.
id superview = [window contentView];本報では,追加する UI コントロールに Button を使用します.まず NSButton インスタンスを生成し,いくつかのプロパティを設定した後,content view の addSubview メソッドを呼び出し View Hierarchy に追加します.
id button = [[[NSButton alloc]なお,setTranslatesAutoresizingMaskIntoConstraints メソッドに NO を指定することで,後述する Constraint が正常に動作します.
initWithFrame:NSZeroRect] autorelease];
[button setTitle:@"Hello World"];
[button setBordered:YES];
[button setBezelStyle:NSRoundedBezelStyle];
[button setTranslatesAutoresizingMaskIntoConstraints:NO];
[superview addSubview:button];
コントロールの配置に Auto Layout システムを使用することで,ユーザーの操作による Window サイズの変化が生じても,View の自動的な配置調整が可能になります.View の配置を記述するには Constraint (拘束) を利用します.拘束内容は,NSLayoutConstraint インスタンスの初期化時に,constraintWithVisualFormat メソッド,または constraintWithItem メソッドにて記述されます.
id h_const = [[NSLayoutConstraintView に Constraint を追加し,拘束を有効にします.
constraintWithItem:superview
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:button
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0] autorelease];
[superview addConstraint:h_const];
2. Controller との関連付け
View と Controller 間でメッセージのやり取りを行うには,Target-Action 機構を利用します.Action とは View の内,特にボタンなどの UI コンポーネントがユーザーの操作を受けて発するメッセージのことです.実装上はコールバックやデリゲートに近く,特定の操作を受けた際に呼び出されるメソッドを登録する形になります.Target は Action を受信するオブジェクトのことで,登録したインスタンスのメソッドが Action の発信時に呼び出されます.
本記事では,Controller を次にように定義しました.
@interface Controller : NSObjectこれを NSButton インスタンスと関連付け,メッセージを受け取れるようにします.
- (void) hello:(id)sender;
@end
@implementation Controller
- (void) hello:(id)sender
{
NSLog(@"Hello World");
}
@end
[button setTarget:[[Controller new] autorelease]];
[button setAction:@selector(hello:)];
最後に以下のコマンドでビルドします.
gcc -framework Cocoa hello.m -o hello実行すると,ボタンが中央に配置されたウィンドウが表示され,ボタンを押すと "Hello World" のログが端末に出力されると思います。

スポンサーサイト