Objective-c 画面遷移について

このQ&Aのポイント
  • Objective-cで画面遷移を行う方法について教えてください。
  • UIScrollViewでスクロールさせる画面と、固定の画面を表示する画面を切り替える方法を教えてください。
  • 特定の位置に表示される画面を作成する方法を教えてください。
回答を見る
  • ベストアンサー

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]]; }

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

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

根本的にプログラムの構成を設計し直すことをお勧めします。 iOSでは、Navigation Controllerや、TabBar Controllerを使って、画面遷移することが標準かつ推奨となっています。あなたのプログラムのように、Viewの上にViewを載せてを繰り返すと、むだにメモリを消費するばかりで、効率が悪いばかりでなく、メモリ不足に起因する、重大なエラーを導く危険があります。OSが用意してくれる画面遷移のシステムを使えば、メモリ配分も適切に行ってくれるので、効率的かつ安全ですし、ほかのiOSアプリと同等の使用感をユーザに与えてくれるので、「なにこれ、なんかださいんですけど」と不評を買うことが少なくなります。 Navigation Controllers file:///Developer/Platforms/iPhoneOS.platform/Developer/Documentation/DocSets/com.apple.adc.documentation.AppleiOS4_3.iOSLibrary.docset/Contents/Resources/Documents/index.html#featuredarticles/ViewControllerPGforiPhoneOS/NavigationControllers/NavigationControllers.html%23//apple_ref/doc/uid/TP40007457-CH103-SW1 なんだかむずかしそうですが、画面遷移のプログラムは、完全にワンパターンでいけますので、一回プログラムを覚えれば、それを単純に繰り返すだけですみます。 さて、あなたのプログラムで、(画面遷移ではなく、単に)インスタンスcontroller(という名前のView)に、子ビュー(subview)として貼り付けた、インスタンスsvc.viewは、親ビューの親ビューであるインスタンスscrollViewの上にあるのですから、いっしょにスクロールするのは、あたりまえといえば、あたりまえです。svc.viewがscrollViewとリプレイスするようなプログラムでないと、ご希望の結果にはなりません。 それと、タップしただけで画面遷移するのは、やっぱりダサイですよ。スワイプ(Swipe)して遷移するようにしないと。なにせ、みんなこれをやりたくで、iPhoneやAndroidを使っているようなものでしょ?

eTakasy
質問者

お礼

迅速なご回答、ありがとうございます。 「Navigation Controller」でやはり作った方がやはり良いんですね。。 実機テストをするとメモリ不足のエラーメッセージも出ていて実際に困っていました。。 ただ、UIScrollViewだとタップやスワイプといったイベントはやはり、サブクラスで 書かなくてはいけないのでしょうか?それだと、また画面遷移の処理を書くのにまたはまってしまう予感が…… その時はまた質問させて下さい。 まずは、Navigation Controllerで一から作り直してみます! 本当にありがとうございました。

その他の回答 (1)

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

関連するQ&A

  • 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]; }

  • 一つの画面でスクロールとフリックをする方法について

    今、画像を左右に数枚スクロールさせれて、かつ、その画像を上や下にフリックすると各々、上や下に他の画像がでてきて、さらに拡大縮小もできるようなコードを書いているのですが、 ViewContorller(以下、VC)にスクロールと上下のフリックのメソッドを書き、 もう一つのPageView(UIScrollVIewクラスを親にもつ。以下、PV)に画像が拡大縮小するようなメソッドをdelegateを使って書いています。 その際に、VCのほうに書いているスクロールのメソッドがフリックのメソッドを邪魔してうまくフリックのtouchメソッドを呼んでくれません。スクロールメソッドを消すと、フリックが使えますが、そうでないときは、スクロールと拡大縮小だけができます。 調べたところ、        scrollView.canCancelContentTouches=NO;        scrollView.delaysContentTouches=NO; を使うと良いというのでやってみたのですが、うまくいきません。 もし、お分かりになる方がいらっしゃいましたら、大変お手数かけますが、ご教授ください。 以下が VC.mです。 xcodeは5.0バージョンです。 - (void)viewDidLoad { [super viewDidLoad]; UIScrollView *scrollView = [[UIScrollView alloc] init]; //ここに先ほどのを入れてみました。 scrollView.canCancelContentTouches=NO; scrollView.delaysContentTouches=NO; scrollView.frame = self.view.bounds; scrollView.contentSize = CGSizeMake(self.view.frame.size.width * kPageNum, self.view.frame.size.height); scrollView.pagingEnabled = YES; [self.view addSubview:scrollView]; for (int i=0;i<kPageNum;i++) { PageView *page = [[PageView alloc] initWithFrame:self.view.bounds]; //setImageメソッドはPVのほうで定義しています。 [page setImage:[NSString stringWithFormat:@"%d.png", i]]; page.frame = CGRectMake( self.view.frame.size.width * i, 0, self.view.frame.size.width, self.view.frame.size.height ); [scrollView addSubview:page]; } } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; _timestampBegan = event.timestamp; _pointBegan = [touch locationInView:self.view]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { static const NSTimeInterval kFlickJudgeTimeInterval = 0.3; static const NSInteger kFlickMinimumDistance = 10; UITouch *touchEnded = [touches anyObject]; CGPoint pointEnded = [touchEnded locationInView:self.view]; NSInteger distanceHorizontal = ABS(pointEnded.x - _pointBegan.x); NSInteger distanceVertical = ABS(pointEnded.y - _pointBegan.y); if (kFlickMinimumDistance > distanceHorizontal && kFlickMinimumDistance > distanceVertical) { return; } NSTimeInterval timeBeganToEnded = event.timestamp - _timestampBegan; if (kFlickJudgeTimeInterval > timeBeganToEnded) { if (distanceHorizontal > distanceVertical) { if(pointEnded.x>_pointBegan.x) {} //上下のフリックだけなのでここには書いていません。 else{}} else{ if (pointEnded.y > _pointBegan.y) { NSLog(@"あ");//NSLogで反応の仕方をみてます。 } else { NSLog(@"い"); } 初心者のため色々と質問の内容から間違いがあるかもしれませんが、宜しくお願い申し上げます。

  • objective-cに関する質問です。

    objective-c初心者です。以下の参考書に載っていた初期化という処理についていまいち理解できません。 理解できない所は、何度も出てくるselfが何者なのか、というコトと、 [self.view addSubview:_textField]; このaddsubviewは何なのかということです。 調べても分からなかったので、親切な方教えて下さいますと幸いです。 よろしくお願い致します。 _____________________________ //初期化 - (void)viewDidLoad { [super viewDidLoad]; //テキストフィールドの生成 _textField=[self makeTextField:CGRectMake(10,20,300,32) text:@""]; [self.view addSubview:_textField]; //書き込みボタンの生成 UIButton* btnWrite=[self makeButton:CGRectMake(55,62,100,40) text:@"書き込み" tag:BTN_WRITE]; [self.view addSubview:btnWrite]; //読み込みボタンの生成 UIButton* btnRead=[self makeButton:CGRectMake(165,62,100,40) text:@"読み込み" tag:BTN_READ]; [self.view addSubview:btnRead]; }

  • objective-c 描画処理について

    初心者ですが、iPhoneアプリを作成しています。 画像を並べてスクロールできるように配列で描画処理を行ないたいのですが、うまくいきません。 今のところのコードはこんな感じです↓ - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray* imageList = [NSMutableArray array]; for (int i=1; i < 20; i++) { UIImage* image = [UIImage imageNamed: [NSString stringWithFormat:@"%d.jpg", i+1]]; [imageList addObject:image]; } MyImageView* imageView = [[MyImageView alloc] initWithImage:imageList]; scrollView.contentSize = imageView.bounds.size; [scrollView addSubview:imageView]; [imageView release]; } どなたか分かる方、教えて頂けますよう宜しくお願いします。

  • 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で困っています教えてください

    objective-cをトライ&エラーで試しながら学習をしている初心者です。タッチした所を中心にまず100×100の正方形を表示し、その後スライダーで正方形の大きさを決めてから画像のトリミングをしたいのですが、正方形が表示されないのと、タッチした位置と切り取られる位置がずれています。上記の内容で行き詰っており、知恵をお借りしたいと思い投稿しました。宜しくお願いします。 ViewController.mの内容 #import "ViewController.h" @interface ViewController (){ // UILabel *label; // UIImageView *uv; //中心の位置 float v; // X座標 float x; // Y座標 float y; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //写真の表示 CGRect rect_uv = CGRectMake(0,20, 360, 360); UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect_uv]; //画像のアスペクト比を維持しUIImageViewサイズに収まるように表示 imageView.contentMode = UIViewContentModeScaleAspectFit; UIImage *image = [UIImage imageNamed:@"hoge.png"]; [imageView setImage:image]; [self.view addSubview:imageView]; // UISliderのインスタンス化 CGRect rect_sd = CGRectMake(50, 400, 200, 10); UISlider *slider = [[UISlider alloc]initWithFrame:rect_sd]; // スライダーの最小値,最大値,値を設定 slider.minimumValue = 0; slider.maximumValue = 500; slider.value = 100; // スライドしている最中に値を調べられるようにする.デフォルトでYESだがサンプルのため slider.continuous = YES; // スライダーの値が変更されたときに呼ばれるメソッドを設定 [slider addTarget:self action:@selector(slider_ValueChanged:) forControlEvents:UIControlEventValueChanged]; // スライダーをビューに追加 [self.view addSubview:slider]; // ラベルの設置 CGRect rect_lb = CGRectMake(300, 400, 100, 30); label = [[UILabel alloc]initWithFrame:rect_lb]; [self.view addSubview:label]; // 標準ボタン例文 UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = CGRectMake(50, 450, 100, 30); [btn setTitle:@"切り取り" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(trim:) forControlEvents:UIControlEventTouchDown]; [self.view addSubview:btn]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /** * スライダーの値が変更されたとき */ - (void)slider_ValueChanged:(id)sender { UISlider *slider = sender; // スライダーの値をログに記述 NSLog(@"スライダーの値:%f", slider.value); // ラベルのテキストを設定 //float v = slider.value; v = slider.value; label.text = [NSString stringWithFormat:@"%2.f",v]; //四角形を描画 CGContextRef context = UIGraphicsGetCurrentContext(); // コンテキストを取得 CGContextStrokeRect(context, CGRectMake(x,y,v,v)); // 四角形の描画 } /** * タッチされたとき */ - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1.anyObjectメソッドでいずれか1つのタッチを取得 // 2.locationViewメソッドで対象となるビューのタッチした座標を取得 CGPoint p = [[touches anyObject] locationInView:self.view]; x = p.x; // X座標 y = p.y; // Y座標 NSLog(@"タップ開始 %f, %f", x, y); //四角形を描画 CGContextRef context = UIGraphicsGetCurrentContext(); // コンテキストを取得 CGContextStrokeRect(context, CGRectMake(x,y,100,100)); // 四角形の描画 } /** * 切り取りボタンが押されたとき呼ばれるtrimメソッド */ -(void)trim:(UIButton*)button{ // ここに何かの処理を記述する // (引数の button には呼び出し元のUIButtonオブジェクトが引き渡されてきます) // 切り抜き元となる画像を用意する。 //UIImage *srcImage = /* UIImagePickerなどから取得したUIImage */ UIImage *srcImage = [UIImage imageNamed:@"hoge.png"]; // 切り抜く位置を指定するCGRectを作成する。 CGRect trimArea = CGRectMake(x, y, v, v); // CoreGraphicsの機能を用いて、 // 切り抜いた画像を作成する。 CGImageRef srcImageRef = [srcImage CGImage]; CGImageRef trimmedImageRef = CGImageCreateWithImageInRect(srcImageRef, trimArea); UIImage *trimmedImage = [UIImage imageWithCGImage:trimmedImageRef]; // 画像表示例文 //UIImage *img = [UIImage imageNamed:@"hoge.png"]; UIImageView *iv = [[UIImageView alloc] initWithImage:trimmedImage]; [self.view addSubview:iv]; } @end

  • スクロールの上にある画像をフリックで変える方法とは

    今、画像を左右に数枚スクロールさせ、かつ、その画像を上や下にフリックすると各々、上や下に他の画像がでてきて、さらに拡大縮小もできるようなコードを書いています。 ViewContorller(以下、VC)にスクロールのメソッドを書き、 もう一つのPageView(UIScrollVIewクラスを親にもつ。以下、PV)に画像が拡大縮小するようなメソッドと上下のフリックのメソッドを書いています。 このPVの中で行う上下のフリックの操作によって、VCにあるスクロールの上に乗っている画像を変えたいのですが、色々と試したのですがその方法が一向にわかりません。もし宜しければ、ご教授ください。宜しくお願い致します。 xcodeは5.0です。 以下、スクロールとその上に画像をのせているpageがあるVC.mのコードです。 このpageにのっている画像をPVのほうのフリック操作で変更させたいと思っています。 - (void)viewDidLoad { [super viewDidLoad]; UIScrollView *scrollView = [[UIScrollView alloc] init]; scrollView.frame = self.view.bounds; scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 3, self.view.frame.size.height); scrollView.pagingEnabled = YES; [self.view addSubview:scrollView]; //AppdelegateでValueというプロパティをつくり、PVでのフリック操作によってこの数値が変動したら、currentpageに反映して、それに対しての画像がでてくるようにしたいつもりです。 AppDelegate *appdelegate=(AppDelegate*)[[UIApplication sharedApplication]delegate]; currentpage=appdelegate.Value; //PageViewにて、画像をいれるメソッドをsetImageでつくっています。 for (int i=1;i<4;i++) { PageView *page = [[PageView alloc] initWithFrame:self.view.bounds]; [page setImage:[NSString stringWithFormat:@"%d.%d",currentpage,i]]; page.frame = CGRectMake( self.view.frame.size.width * (i-1), 0, self.view.frame.size.width, self.view.frame.size.height ); [scrollView addSubview:page]; }

  • [再]objective-c 描画処理について

    前回質問させて頂きましたが、まだ抜け出せていないので教えて下さい。 ↓↓↓ -------------------------------------------------------------------------------------------------------------- 初心者ですが、iPhoneアプリを作成しています。 画像を並べてスクロールできるように配列で描画処理を行ないたいのですが、うまくいきません。 今のところのコードはこんな感じです↓ - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray* imageList = [NSMutableArray array]; for (int i=1; i < 20; i++) { UIImage* image = [UIImage imageNamed: [NSString stringWithFormat:@"%d.jpg", i+1]]; [imageList addObject:image]; } MyImageView* imageView = [[MyImageView alloc] initWithImage:imageList]; scrollView.contentSize = imageView.bounds.size; [scrollView addSubview:imageView]; [imageView release]; } どなたか分かる方、教えて頂けますよう宜しくお願いします。 -------------------------------------------------------------------------------------------------------------- ↓ NSArray *initWithImage;と引数で渡しましたが、 「MyImageView* imageView = [[MyImageView alloc] initWithImage:imageList];」 の部分で、「Incompatible pointer sending 'NSMutableArray *' to parameter of type 'UIImage *'」とエラー表示され、実行すると、 「Tread1 : Program received signal: "SIGABRT"」で落ちてしまいます。

  • Objective-c画面推移のメモリ管理について

    iPhoneアプリ開発を初めて間もなく拙い質問ですがお願いします。 StoryBoardを使わずにxibを指定して直接画面推移を行っています。 その周辺のコードは http://www.bhnt.co.jp/blog/雑記/社員:cobra/イチから学ぶiphoneipadアプリ開発-第6回-「interface-builderを使って ...を参考にしました。 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { SecondViewController *vc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self presentViewController:vc animated:NO completion:nil]; // [self removeFromParentViewController]; // [self.view removeFromSuperview]; } 画面がタッチされたときにSecondViewControllerを呼び出して、画面を遷移しています。 SecondViewControllerにも似たコードを記述しMainViewControllerに遷移しています。 これを繰り返していると数MByteずつ使用メモリが増えていきます。まだメモリも小さく支障は全くないのですが、いずれ悩まされる前に解決したいと思い質問しました。 遷移したあとに元の画面が破棄されていないのでは無いかと思い、コメントアウトにしてある下二行を追加してみましたが、結果は変わりませんでした。 破棄されたことを示すviewDidDisappearをNSLogで確認してみたところ、呼び込まれているのですが、これはC++などでいうデストラクタとは似つかない処理でしょうか? 長々と要点の掴みづらい質問ですがどうかよろしくお願いします。

  • Objective-Cのメモリ管理

    はじめまして。 iphoneアプリを作っていてメモリ管理について不明な点があるので教えて下さい。 memoryViewController.h ============================================== #import <UIKit/UIKit.h> @interface memoryViewController : UIViewController { id obj; } @property(retain)id obj; @end =============================================== memoryViewController.mm(一部) =============================================== @implementation memoryViewController @synthesize obj; - (void)viewDidLoad { [super viewDidLoad]; self.obj = [[NSObject alloc] init]; NSLog(@"count = %d", [obj retainCount]); } =============================================== 下記の部分についてです。 self.obj = [[NSObject alloc] init]; 「self.」を付けた場合retainCountは2で、付けなかった場合retaionCountは1になります。 何故違ってくるのかが理解できません。 教えて下さい。

専門家に質問してみよう