目的
ユーザーの画面へのタッチをカスタムUIViewで検出する

主要クラス
UIView

使用テンプレートプロジェクト
Window-based Application

NOTE
 今回のタッチ検出はUIViewを継承したカスタムUIViewでおこなう。
 View-based Applicationテンプレートは、カスタムUIViewControllerは用意しているが、カスタムUIViewは用意してくれない。
 ここからカスタムUIViewに変更する作業はXIBファイルの変更も必要になり、もともとの目的であるタッチを検出する処理以外の作業が多くなってしまうためWindow-based Applicationテンプレートを使う事にした。

サンプル実装説明
 カスタムUIViewを用意しタッチを検出、その座標をコンソールに表示する。

 プロジェクトの名称:
Touch

 カスタムUIViewの作り方。

 ファイル>新規ファイル...メニューを選ぶ。

$テン・シー・シー-1

 表示されるダイアログで Cocoa Touch ClassのObjective C classのUIViewを選ぶ。

 カスタムUIViewの名称:
TouchView


$テン・シー・シー-2

 次に出てくるダイアログでは名前以外は特に指定し直すところはない。
 プロジェクトに追加のメニューでTouchが選ばれ、ターゲットTouchにチェックが入っていればいい。

 カスタムUIViewではタッチを検出するために以下のメソッドを実装する。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

 
 このメソッドはユーザーがタッチされた直後に呼び出されるメソッド。通常UIViewが処理を担当するが、カスタムUIViewに実装する事で、先に自分が受け取ることができるようになる。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
CGPoint pt = [touch locationInView:self];
printf("point = %lf,%lf\n", pt.x, pt.y);
}

 自分のビュー内のタッチされた座標を取り出しprintfでコンソールに出力している。
 NSSetは複数のNSObjectを継承したインスタンスをひとくくりにするクラス。anyObjectメッセージを送る事で、その中のひとつのインスタンスを返す。
 UIViewは指定しない限り指一本分の情報しか扱わない。そのためanyObjectでインスタンスを一つ取り出せば、目的は達成する。
 取り出したインスタンスはUITouchクラスのインスタンスであるので、locationInViewメッセージでUIViewインスタンスを指定する事で、指定したUIView上の座標を得る事ができる。

 このカスタムUIViewを画面上に表示するにはTouchAppDelegateのapplicationDidFinishLaunchingメソッドに以下の処理を追加する。
- (void)applicationDidFinishLaunching:(UIApplication *)application {    
TouchView* view = [[TouchView alloc]
initWithFrame:CGRectMake(100, 100, 200, 200)];
view.backgroundColor = [UIColor greenColor];
[window addSubview:view];

[window makeKeyAndVisible];
[view release];
}

 ここでintiWithFrameで指定している矩形は任意でよい。
 また、そのままだと貼付けられたカスタムUIView(TouchView)の位置がわからないのでview.backgroundColorを設定しているがタッチ検出に必要な処理というわけではない。
 addSubview:viewで画面上に追加される。
 initWithFrameによってTouchAppDelegateに作成したTouchViewインスタンスの管理責任が発生するが、addSubview:viewにより管理責任をwindowにも受け持たせる事になる。このままではTouchAppDelegate とwindowの2つのインスタンスがTouchViewインスタンスに対し管理責任を持つことになる。
 そのため[view release]によりTouchAppDelegate側の管理責任を放棄している。

プロジェクト
Touch00.zip

検討
 このサンプルでは緑色の領域だけタッチを検出しコンソールに座標を表示することがわかる。
 しかし実際のiPhoneアプリケーションはタッチ以外にドラッグという動作にも対応している。これにはtouchesBegan以外の実装が必要。これは次のドリルで。
 また、タッチ検出はUIViewではなくUIViewControllerでも可能。この場合タッチ情報を通知される順を理解して使う必要がある。これも別のドリルで。


関連ドリル
コンソールを表示する。