• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:UIImageViewをタップで、画面遷移するには)

UIImageViewをタップして画面遷移する方法

このQ&Aのポイント
  • iPhoneアプリ開発において、UIImageViewをタップした際に画面遷移する方法について質問です。
  • UIViewControllerのサブクラスにはNomal_topViewController、UIViewのサブクラスにはPreviewView、そしてその上にUIImageViewのサブクラスであるTapImageを表示しています。
  • TapImageをタップした際に新しいViewControllerを開くか、全画面表示のViewを開く処理を実装したいのですが、どのようにすれば良いでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.2

学び始めて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を使ったほうがいいと思いますね。

その他の回答 (1)

  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.1

まず、あなたの学習がどこのレベルまで進んでいるか、その情報が必要です。あなたにとっては既知のことを繰り返し聞かされるのは退屈でしょうし、回答する側にとっても無駄骨を折りたくありません。 UINavigationControllerを使って、画面遷移はできますか? UIViewの「subviews」メソッドを使って、サブビューの管理(並び替え、追加、削除)ができますか? > TapImageでタップは検出できています。 しの検出のために、どういうコードを書きましたか?ここに抜粋してください。そのコードを見れば、あなたの学習達成度を推測することができます。 それと……UIImageViewよりUIButtonを使ったほうがかんたんだと考えませんでしたか?そしてあえてUIButtonではなくUIImageViewを使う選択をした理由はなんですか?

hiyokoclub0
質問者

補足

記すべき内容が書かれていない状態で質問してしまい大変申し訳ありません。 objective-Cを学び始めて3週間ほどです。 ModallViewでの画面遷移はできます。 addsubviewを用いてもviewの追加は出来ますが、並び替え、削除は理解できていません。 - (void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Touches began"); //タッチオブジェクトに追加 NSArray* objects=[touches allObjects]; //再描画(4) [self setNeedsDisplay]; NSString *str; str =[[NSString alloc]init]; //array型のobjectsをstring型に変換する for(id obj in objects){ str = [NSString stringWithFormat:@"%@",obj]; } // 文字列strの中に@"AAA"というパターンが存在するかどうか NSRange searchResult1 = [str rangeOfString:@"frame = (0 0; 200 320);"]; NSRange searchResult2 = [str rangeOfString:@"frame = (200 0; 200 320);"]; NSRange searchResult3 = [str rangeOfString:@"frame = (400 0; 200 320);"]; NSRange searchResult4 = [str rangeOfString:@"frame = (600 0; 200 320);"]; NSRange searchResult5 = [str rangeOfString:@"frame = (800 0; 200 320);"]; if(searchResult1.location != NSNotFound){ NSLog(@"page1"); pp = @"page1"; NSLog(@"public : %@",pp); /*UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello!" message:@"You tapped page1!" delegate:nil cancelButtonTitle:@"Oh yes!" otherButtonTitles:nil]; [alert show]; [alert release];*/ }else if(searchResult2.location != NSNotFound){ NSLog(@"page2"); pp = @"page2"; NSLog(@"public : %@",pp); /* UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello!" message:@"You tapped page2!" delegate:nil cancelButtonTitle:@"Oh yes!" otherButtonTitles:nil]; [alert show]; [alert release];*/ }else if(searchResult3.location != NSNotFound){ NSLog(@"page3"); pp = @"page3"; NSLog(@"public : %@",pp); /* UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello!" message:@"You tapped page3!" delegate:nil cancelButtonTitle:@"Oh yes!" otherButtonTitles:nil]; [alert show]; [alert release];*/ }else if(searchResult4.location != NSNotFound){ NSLog(@"page4"); pp = @"page4"; NSLog(@"public : %@",pp); /* UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello!" message:@"You tapped page4!" delegate:nil cancelButtonTitle:@"Oh yes!" otherButtonTitles:nil]; [alert show]; [alert release];*/ }else if(searchResult5.location != NSNotFound){ NSLog(@"page5"); pp = @"page5"; NSLog(@"public : %@",pp); } } というコードです。 タップした画像によって開くviewを選びたいため、このように書きました。 UIImageViewを選んだ理由としましては、top_ViewControllerで追加した画像枚数によってImageViewを自動生成する、ということを行いたかっったためです。 -(UIView*)viewForItemAtIndex:(BSPreviewScrollView*)scrollView index:(int)index{ CGRect imageViewFrame = CGRectMake(0.0f, 0.0f, 200, 320); TapImage *imageView = [[[TapImage alloc] initWithFrame:imageViewFrame] autorelease]; imageView.image = [UIImage imageNamed:[self.scrollPages objectAtIndex:index]]; imageView.contentMode = UIViewContentModeCenter; return imageView; } コードはこのように書きました。 TapImageとPreviewScrollViewは別のViewControllerでも用いるため、別ファイル化してあります。 このような説明でよろしかったでしょうか。 至らない部分が多くて申し訳ありません。

関連するQ&A