学び始めて3週間にしては、ひじょうに勉強なさっているように思えます。りっぱです。
が、まだ勉強なさっていない項目も、多々残っているといわなければなりません。サンプルコードや、Appleが提供するユーザーズガイドをもっと読みあされば、「こういうときはこう書く」という定番のコードを身につけることができるでしょう。
まず、レスポンダチェーン(Responder Chain)という考え方があるのは、ごぞんじですか?
UIImageView(あるいはUIViewとそのサブクラス)のインスタンスをタッチすると、タッチしたというイベントが発生します。そのイベントをキャッチするのが、「- (void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event」などのメソッドですが、そのメソッドでキャッチされると、イベント自体は消滅します。しかし、UIResponder(のサブクラス。UIView、UIViewControllerが含まれる)インスタンスにイベントをキャッチするメソッドがないと、イベントはそこで消滅せずに、そのインスタンスの上位インスタンス(superview)に受け渡されます。そこでもキャッチされないと、つぎのインスタンスに……と繰り返されます。この受け渡しをレスポンダチェーンといいます。なお、UIViewインスタンスが、UIViewControllerを持っている場合は、いったんUIViewControllerインスタンスに渡されてから、superviewにイベントが渡されます。だれにも受け取られなかったイベントは、UIWindowインスタンスに渡され、そこでもキャッチされなければ、UIApplicationに渡され、最後は闇の彼方に消え去ります。
今回のプログラムでは、UIImageViewサブクラスのインスタンスがタッチのイベントを受け取り、UIViewControllerサブクラスのインスタンスがイベントをキャッチしています。UIImageViewでなく、UIButtonを使ったほうがいいのでは?と私がいうのは、UIControlクラス(UIButtonは、UIControlのサブクラス)は、タッチのイベントを自身でキャッチして処理(Target - Actionのシステム)するので、わかりやすいプログラムになるという意味です。Target - Actionなら、コードを書かずにInterface Builderで視覚的に編集することもできますし。
タッチイベントの処理には、定型のコードがあります。
- (void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *theView = touch.view;
~
}
この「anyObject」という、配列要素の中の任意の要素という、ほかのAPIではなかなかおめにかかれないメソッドによって、UITouchというタッチイベントをあつかうクラスのインスタンスを取得します。「任意の」ですますのは、どのUITouchインスタンスでも、次の行「UIView *theView = touch.view;」の結果が変わらないからです。
UITouchのプロパティ「view」は、タッチイベントが発生したビューを指します。これでどのビューがタッチされたかがわかる仕組みです。
あるインスタンスが、ほかの変数に代入されたインスタンスと同一かどうかを調べるのに、「isEqual:」というメソッドを使います。
if ([theView isEqual: imageView1]) {~}
ここまで学習すれば、ばっさりとコードを切り捨てて、短い行数で処理できるのではないでしょうか?
UIView(のサブクラス)インスタンスの識別には、「tag」というプロパティを使う方法もあります。このプログラムでは、こちらのほうがいいかもしれません。tagの型は符号付き整数です。
NSLog(@"Next Page = %@", [NSString stringWithFormat: @"Page %d", theView.tag]);
こんなこともできます。
しかし、やはり私はUIButtonを使ったほうがいいと思いますね。
投稿日時 - 2011-12-08 18:35:37