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

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

UIImageViewをタップで、画面遷移するには

iphoneのアプリ開発のなかでわからない部分があるので、投稿しました。 UIViewControllerクラスのサブクラス(Nomal_topViewController)の上に、UIViewクラスのサブクラス(PreviewView)の上に、UIImageViewのサブクラス(TapImage) というレイヤー順で表示しているのですが、TapImageをタップした際、新しいViewControllerを開く、もしくは全画面表示のViewを開く。という処理を行いたいのですが、どのような処理を実装すればよいのでしょうか? TapImageでタップは検出できています。 わかる方いましたら、ご返答よろしくお願いします。

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

  • ベストアンサー
  • 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

  • Objective-C ボタンを動かすには

    Objective-Cはまったくの初心者で、iPhone用のアプリを作るのに書籍を見ながらサンプルをいじっています。 画像をタップしたらその画像自体が動くようなものを作りたいのですが、 RoundRectButtonを1個だけ配置して 【imageTestViewContollorer.h】 @interface imageTest1ViewController : UIViewController { IBOutlet UIButton *myButton; } -(IBAction)tapBtn; @end 【imageTestViewContollorer.m】 @implementation imageTestViewController -(IBAction)tapBtn{ myButton.center=CGPointMake(50,50); [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:2]; myButton.center=CGPointMake(160, 240); [UIView commitAnimations]; } としてみましたが、コンパイルエラーなどはありませんでしたが、ボタンを押しても何も起こりませんでした。 IBOutlet UIButtonが臭いような気もしているのですが、UIImageViewにするとRoundRectButtonと線を繋げなくなりますし、どう直してよいか見当もつかず困っています。 画像がタップされたら動く、みたいなものをそもそもRoundRectButtonに画像を割り当てた方がいいのかImageViewにタップされた場合の処理を割り当てた方がいいのかどうかもよくわかりません。 よろしくお願いいたします。

  • objective-cで困っています教えてください

    下記のようにUIViewの上にUIImageViewを配置し、そこにUIImageをUIViewContentModeScaleAspectFitで表示させています。 表示している画像タップして、座標をとりたいと考えています。 UIImageView(UIImage)上だけをタップのエリアにしたいのですが、画面全体がタップのエリアになってしまいます。また、画像のアスペクト比を維持しUIImageViewサイズに収まるように表示しているので、タップでとれたUIImageView上の座標と、画像上の座標にズレができてしまいます。UIImageViewサイズに収まるように表示された画像上の位置から元の画像の座標を取得する方法を教えてください。 #import "ViewController.h" @interface ViewController (){ UIImageView *imageView; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CGRect rect = CGRectMake(0,20, 360, 480); imageView = [[UIImageView alloc] initWithFrame:rect]; imageView.backgroundColor = [UIColor redColor]; //画像のアスペクト比を維持しUIImageViewサイズに収まるように表示 imageView.contentMode = UIViewContentModeScaleAspectFit; UIImage *image = [UIImage imageNamed:@"hoge.png"]; [imageView setImage:image]; [self.view addSubview:imageView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /** * タッチされたとき */ - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint p = [[touches anyObject] locationInView:imageView]; float x = p.x; // X座標 float y = p.y; // Y座標 NSLog(@"タップ開始 %f, %f", x, y); } @end

  • objective-c 画面遷移について

    今、iPhoneアプリを開発しています。簡単なカードゲームですが、 画面遷移について困っています。 サブクラス内のタッチイベントに、 [super presentModalViewController:viewController animated:YES]; と記述し、画面を切り替えたいのですが、 「'UIView' may not respond to 'presentModalViewController : animated:'」と 注意メッセージが表示され、 また、実行すると「Thread 1: received signal: "SIGABRT"」 となり、落ちてしまいます。 何分、初心者なもので、どこからどう手をつけたら良いのか分かりません。 色々調べたのですが、中々該当する答えが見つかりませんでした。 どなたか、お分かりになる方教えて頂けないでしょうか。 宜しくお願いします。

  • Objective-c 画面遷移について

    やはり、画面遷移ではまっていますので、助けて下さい。 navigationControllerで作成しています。 (内容は以前に質問させて頂いているものとほぼ同じですが、) 「FirstViewController」はUIScrollViewでスクロールさせている画面で、タッチイベントを取得する為に UIScrollView のサブクラスを作っています。 そこでタッチすると、「SecondViewController」へ遷移するようにしたいのですが、下記のように単純にpushViewControllerを使ってサブクラスへ書くと、「Property 'navigationContoroller' not found on object of type 'MyScrollview'」というエラーが表示されてしまいます。 このクラスへ書いたらいけないというのは、なんとなく分かりますが、かと言って何からどう手をつければ良いのか分かりません…… 問題なく画面遷移させるにはどうしたらよいのでしょうか。 詳しく教えて頂けると、大変助かります。。 ↓FirstViewController.h↓ @interface FirstViewController : UIViewController{   MyScrollview *controller; IBOutlet UIScrollView *scrollView; } ↓FirstViewController.m↓ - (void)viewDidLoad { controller = [[ MyScrollview alloc] initWithFrame:CGRectMake(0, 0, 1100, 1100)]; self.view = controller; [super viewDidLoad]; [super loadView]; scrollView.contentSize = controller.frame.size; [scrollView addSubview:controller]; } ↓MyScrollview .h↓ @interface MyScrollview : UIView<UIScrollViewDelegate>{ } @end ↓MyScrollview .m↓ -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{ ~省略~ SecondViewController *mvc = [[[SecondViewController alloc] initWithNibName:nil bundle:nil] autorelease]; [self.navigationController pushViewController:mvc animated:YES]; }

  • Objective-c  画面遷移について

    毎回、初歩的な質問内容で申し訳ありませんが、困っているので教えて下さい。 「FirstViewController」はUIScrollViewでスクロールさせている画面で、タッチイベントを取得する為に UIScrollView のサブクラスを作っています。 そこでタッチすると、「SecondViewController」へ固定の画面で遷移するようにしたいのですが、「SecondViewController」の画面もそのままスクロール画面で表示されてしまいます。。。 「SecondViewController」をスクロールさせず、位置x=0 y=0で表示させるにはどうしたら良いのでしょうか? 詳しく教えて頂けると、大変助かります。。 ↓FirstViewController.h↓ @interface FirstViewController : UIViewController{   MyScrollview *controller; IBOutlet UIScrollView *scrollView; } ↓FirstViewController.m↓ - (void)viewDidLoad { controller = [[ MyScrollview alloc] initWithFrame:CGRectMake(0, 0, 1100, 1100)]; self.view = controller; [super viewDidLoad]; [super loadView]; scrollView.contentSize = controller.frame.size; [scrollView addSubview:controller]; } ↓MyScrollview .h↓ @interface MyScrollview : UIView<UIScrollViewDelegate>{ } @end ↓MyScrollview .m↓ -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{ SecondViewController *svc; svc = [[SecondViewController alloc] init]; [self addSubview:[svc view]]; }

  • 画面遷移について

    早速質問なんですが、今 1.ホーム画面は地図(google Map)を表示、また画面遷移用のボタンを設置してある。 2.ボタンを押すとカメラを使う画面に遷移し、そこでとりあえず写真を撮る。(ここではカメラを実行するActivityと、SurfaceView を継承したクラスを別クラスにて実装しております。) 3.取った後に勝手に画面遷移させ(元のMap画面へ)、撮った写真の緯度、経度を取得したうえで現在地情報を表示させる。→表示させる際はFacebookなどにある、ピンをMap上に表示させるような感じで、さらにその場所の住所、画像も表示させる、といったイメージです。 このような仕様のアプリを作っております。簡単に言えば、写真を撮ったら現在地の情報がわかる!といったアプリです。 ここで、カメラ画面から元のMap画面に画面遷移させたいのですが、通常Activity間の画面遷移はIntentを使用するのが一般的ですが、この場合だとどのように実装すれば可能でしょうか? 自分としてはHandlerクラスのメンバをSurfaceView を継承したクラスで用意して、Activityに対してそのクラスを呼び出すコードを実装すれば行けるのかなぁ…と考えているのですが。 初対面でいきなりの質問で誠に申し訳ございませんが、ご回答お待ちしております。 必要であればプログラムコードもお送りいたします。よろしくお願いいたします。

    • ベストアンサー
    • Java
  • splitView 詳細画面左上[戻る]の動作

    初めて質問させていいただきます。 iOS開発の初心者です。Xcode4.6.3 storyboard(iPad) にてspritVewControllerを使った場合に、以下の実装をしたいのですが、その方法が分からず困っております。 何卒、よろしくお願いいたします。 【前提】 ・Single View Applicationテンプレート使用して、最初のviewControllerは削除します。 ・splitViewControllerを追加します。 ・splitViewControllerの「Is Initial View Controller」にチェックします。 ・下記サイトを参考にして、Main と Detail 画面は表示されるまでの最低限の実装はしています。(iPad 横、縦切り替えによって、Main と Detail 画面も切り替わる状態です)  http://program.station.ez-net.jp/special/handbook/objective-c/uisplitviewcontroller/implement.asp 【困っている事(やりたい事)】 ・iPad縦向きのときだけ、detail画面の左上ボタン(Mainに戻るボタン)をタップしたとき、自前で実装するactionメソッド(下記参照:backButtonEvent)へ飛ばして、また、このとき、左上ボタンをタップしたときの既存動作(左側からMain画面がスライド表示される)は維持したいのですが、以下の実装をしたところ、自前で追加したactionメソッドには飛びましたが、既存動作(左側からMain画面がスライド表示される)がされなくなりました。 =(EzDetailViewController.h)==★行が追加したところです ★- (IBAction)backButtonEvent:(id)sender; === =(EzDetailViewController.m)==★行が追加したところです - (void)splitViewController:(UISplitViewController*)splitController willHideViewController:(UIViewController*)viewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)popoverController { // 渡された UIBarButtonItem に表示するタイトルを設定します。 barButtonItem.title = @"戻る"; ★ barButtonItem.target = self; ★ barButtonItem.action = @selector(backButtonEvent:);     :     : } ★- (IBAction)backButtonEvent:(id)sender ★{ ★ NSLog(@"Call in backButtonEvent."); ★} === そもそも、既存のbarButtonItemにaction追加したのがいけないのでしょうか。 ※これによって、既存動作処理が行われなくなったと推察していますが。。。 それとも、追加したactionメソッド内で、既存動作処理と同等のことを実装してあげないといけないのでしょうか。(もしそうであれば、この既存動作処理と同等の実装方法をご教授ください) はたまた、他の解決方法等ありましたら、是非、お教えいただきたく、よろしくお願いいたします。

  • TableViewでタップした時にキーボードを隠す

    ObjectiveCを用いてiPhnoneアプリ開発の勉強をしています。 TableViewControllerのセルにUITextFieldを設置し、そのTextFieldをタッチして表示されたキーボードを キーボードの外がタップされた時に引っ込める(隠す)処理をしたいのですが、うまくできませんでしたので助言をいただきたいです。 Tap Gesture Recognizerを用いる方法や touchesBeganメソッドを用いてタップを検知し[self.view endEditing:YES];でキーボードを閉じる という方法を試したのですが、これらたUIViewControllerでないとできないようで、 キーボードの外をタップしても、セルが選択されてしまい、キーボードは閉じませんでした。 この問題に関して、以下のサイトが参考になると思ったのですが、 http://onno.jp/dev/2012/02/uitableview-touchesbegan-uiviewcontroller.html >IB で TableView のクラスを TouchableTableView に変更 という部分が、どこを指しているのか分からず、どうしたら良いのか分かりません。 どこのTableViewのクラスを、TouchableTableViewに変更したら良いのでしょうか? 試しにキーボードを引っ込ませる処理を組み込みたいTableViewControllerのスーパークラスを UITableViewController から TouchabeTableViewに変更してみましたが、うまくいきませんでした・・ タップした時にキーボードが引っ込ませたいTableViewControllerと、 新たに作成したTouchableTableViewはどのようにして関連付けるのでしょうか? 以下にTouchableTableViewのソースコードを書いておきます。 (Xcode6になり、Fileの新規作成画面が変わり、クラスの書き方がいつもと違うようになっているのが気になりますが・・・。) ----------- ■TouchableTableView.h #import <UIKit/UIKit.h> @interface UITableView (TouchableTableView) @end ■TouchableTableView.m #import "TouchableTableView.h" @implemention UITableView (TouchableTableView) - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.nextResponder touchesBegan:touches withEvent:event]; [super touchesBegan:touches withEvent:event]; } @end --------- 回答お願いします

  • 画面遷移したVCから戻る時に元のVCにデータを渡す

    ObjectiveCを用いてiPhoneアプリ製作の勉強をしています。 ViewController上に設置したボタンで接続したTableViewControllerのセルをタッチしたとき、 そのセルの情報を元のViewControllerのラベルに表示するという処理を組みたいのですが、うまく行きません。 こちらのサイトを参考にしています。 http://kikuchy.hatenablog.com/entry/2013/11/04/Segue_%E3%81%A7%E7%94%BB%E9%9D%A2%E9%81%B7%E7%A7%BB%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AB%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E6%B8%A1%E3%81%97%E3%81%A6%E3%81%BF TableViewControllerのセルがタッチされた時、prepareForSegueメソッドの中のLogが表示されないので、このメソッドが実行されていないように思います。 以下にコードを晒します。 ViewController.m上でproperty宣言されているUILabel *rowNumはストーリーボード上で ViewControllerと接続されています。 ■ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController @property NSInteger rowNumber; @end ■ViewController.m http://www.dotup.org/uploda/www.dotup.org4992395.txt ■selectTableViewController.h http://www.dotup.org/uploda/www.dotup.org4992392.txt ■selectTableViewController.m http://www.dotup.org/uploda/www.dotup.org4992394.txt よろしくお願いします。

  • [Objective-C]キーボード表示切り替え

    Objective-CでiPadアプリケーションを作成しています。 添付画像のように、 「キーボード入力」と「タグ入力」を切り替えることができるような 仕組みをつくりたいと思っています。 (添付ははてなブックマークアプリのタグ付け画面です) どのように実装方法を考えれば、この操作性が実現できるのかわからずにいます。 ソフトウェアキーボードは常時表示させておいて、 その上にタグ用のUIViewをかぶせることができるのか? (試しに実装してみるとソフトウェアキーボードの上にUIViewは被せられませんでした) もしくは、ソフトウェアキーボードを非表示にして、 その位置にタグ用UIViewを表示させるのか? (テキストエリアをタップするとキーボードが再表示されてしまう問題あり) アイディア、コードサンプルなど、 アドバイス頂ければ幸いです。 どうぞよろしくお願いいたします。

専門家に質問してみよう