FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

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 を関連付ける方法を説明します.

以下にサンプルコードを示します.
#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]
initWithFrame:NSZeroRect] autorelease];
[button setTitle:@"Hello World"];
[button setBordered:YES];
[button setBezelStyle:NSRoundedBezelStyle];
[button setTranslatesAutoresizingMaskIntoConstraints:NO];

[superview addSubview:button];
なお,setTranslatesAutoresizingMaskIntoConstraints メソッドに NO を指定することで,後述する Constraint が正常に動作します.

コントロールの配置に Auto Layout システムを使用することで,ユーザーの操作による Window サイズの変化が生じても,View の自動的な配置調整が可能になります.View の配置を記述するには Constraint (拘束) を利用します.拘束内容は,NSLayoutConstraint インスタンスの初期化時に,constraintWithVisualFormat メソッド,または constraintWithItem メソッドにて記述されます.
id h_const = [[NSLayoutConstraint
constraintWithItem:superview
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:button
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0] autorelease];
View に Constraint を追加し,拘束を有効にします.
[superview addConstraint:h_const];

2. Controller との関連付け
View と Controller 間でメッセージのやり取りを行うには,Target-Action 機構を利用します.Action とは View の内,特にボタンなどの UI コンポーネントがユーザーの操作を受けて発するメッセージのことです.実装上はコールバックやデリゲートに近く,特定の操作を受けた際に呼び出されるメソッドを登録する形になります.Target は Action を受信するオブジェクトのことで,登録したインスタンスのメソッドが Action の発信時に呼び出されます.
本記事では,Controller を次にように定義しました.
@interface Controller : NSObject
- (void) hello:(id)sender;
@end

@implementation Controller
- (void) hello:(id)sender
{
NSLog(@"Hello World");
}
@end
これを NSButton インスタンスと関連付け,メッセージを受け取れるようにします.
[button setTarget:[[Controller new] autorelease]];
[button setAction:@selector(hello:)];

最後に以下のコマンドでビルドします.
gcc -framework Cocoa hello.m -o hello
実行すると,ボタンが中央に配置されたウィンドウが表示され,ボタンを押すと "Hello World" のログが端末に出力されると思います。
cocoa_without_xcode_result.png
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

Ishida Akihiko

Author:Ishida Akihiko
FC2ブログへようこそ!

免責事項
当サイトに掲載する記事内容は,必ずしも正確性,信頼性,妥当性,有用性,完成度などを保証しません.記事の利用はすべて自己責任でお願いします.当サイトに掲載された内容によって発生したいかなる損害に対しても,管理人は一切の責任を負いかねます.
最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
アクセスカウンター
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。