• 締切済み

Xcodeで子のViewから親の変数を変更する

こんにちは 現在Xcodeでの作業をしています。 画面の遷移の際に現在は (親から子どもへの値を渡す場合<遷移する場合>) ViewcontrollerA *svc = [[ViewcontrollerA alloc] init]; svc->hogehoge = 1; //値などを入れる場合 [self presentModalViewController:svc animated:yes]; [self.parentViewController dissmissModalViewControllerAnimated:YES]; と値を入れているのですが、 逆に上記のAという子どもの(インスタンス内)から親の変数をいじるにはどうすればいいですか? super->parenthogehoge =1 みたいにできればいいのですが、これだとうまくいかなくて・・・。 よろしくお願い致します。

みんなの回答

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

おっとっと、かんじんの「子のViewから親の変数を変更する」について、なにも触れないままでしたね。その前段階のコードを書くのに、時間を費やしてしまって、忘れてしまってました。 ChildViewController.mに、つぎのアクションメソッドを追加します。Interface Builder上で、ボタンなどに紐付けしてください。 - (IBAction)set3: (id)sender { self.parent.value = 3; } ParentViewControllerのほうで、なんらかのプロパティvalueの値を出力するコードを、適当に書いて、じっさいに値が3になっているか、確認してください。

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

No.1の回答の続きです。 画面遷移時のプログラムのポイントは、オブジェクトがいつ生成されるか、それとオブジェクトの参照と操作のタイミングが合うかどうか、です。ここでいうオブジェクトとは、View Controller、その上のView、それに付属しているボタンなどのコントロール、文字列や数値など、ひっくるめてです。 オブジェクトが生成され、完了する前に、そのオブジェクトを参照したり、操作しようとしても、うまくいきません。つねに、そのオブジェクトは、いつ生成されるのか、意識しながらプログラムを書く必要があります。 No.1のサンプルコード、ChildViewController.mで、データ参照の実装を、viewDidLoad:ではなく、viewDidAppear::に行ったというのは、まさにそれが理由です。おそらく0.1秒に満たない差だと思いますが、後者のメソッドが、前者より後に実行され、その間にオブジェクトの生成が進行していることがわかります。 ParentViewControllerからChildViewControllerのプロパティを参照、操作するのではなく、ChildViewControllerから、ParentViewControllerのプロパティを参照する手順をとっているのも、そういう理由です。

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

まず、回答に入る前に、他インスタンスから、インスタンス変数を参照するのはやめましょう。Objective-Cの仕様として、「->」を使ってできることにはなっていますが、いろいろ問題をはらんでいるので、実践では推奨されず、かわりにプロパティの参照を行うことになっています。プロパティについては、書籍やネット検索でお調べください。「Objective-C プロパティ アクセッサメソッド」というようなキーワードで検索すると、有益な情報にヒットするでしょう。 以下、そのプロパティを使って、サンプルコードを書いてみます。 ParentViewControllerからChildViewControllerに画面遷移し、ChildViewControllerからParentViewControllerのプロパティを参照します。 なお、Modal Viewでなく、Navigationによる画面遷移を行っています。 /* ParentViewController.h */ #import <UIKit/UIKit.h> @interface ParentViewController : UIViewController @property (assign) int value; // ChildViewControllerに渡す値 - (IBAction)goChild: (id)sender; @end /* ParentViewController.m */ #import "ParentViewController.h" #import "ChildViewController.h" @interface ParentViewController () @end @implementation ParentViewController - (IBAction)goChild: (id)sender { self.value = 11; // 仮に11としておく ChildViewController *childViewController = [[ChildViewController alloc] initWithNibName: @"ChildViewController" bundle: nil]; [self.navigationController pushViewController: childViewController animated: YES]; childViewController.parent = self; [childViewController release]; } @end /* ChildViewController.h */ #import <UIKit/UIKit.h> @class ParentViewController; // ヘッダファイルをインポートせずに、クラスを宣言するときに必要 @interface ChildViewController : UIViewController @property (nonatomic, retain) ParentViewController *parent; @property (nonatomic, retain) IBOutlet UILabel *result; // ラベルに結果を表示 @end /* ChildViewController.m */ #import "ChildViewController.h" #import "ParentViewController.h" @interface ChildViewController () @end @implementation ChildViewController - (void)viewDidAppear:(BOOL)animated // viewDidLoad:に実装すると、うまく働かない。 { [super viewDidAppear: animated]; int parentValue = self.parent.value; self.result.text = [NSString stringWithFormat: @"The parent value = %d", parentValue]; } @end

関連するQ&A

  • iPhoneアプリの開発についてです。

    元のビューからモーダルで表示させるビューに画面遷移に伴い値を受け渡したいのですがうまくいきません。 私は主に画面遷移する際 ○○○ *△△△ = [self.storyboard instantiateViewControllerWithIdentifier:@"□□□"]; [self presentViewController:△△△ animated:YES completion: nil]; とコーディングしています。 インスタンス生成部分を ○○○ *△△△ = [[○○○ alloc] init]; とすれば簡単に値が受け渡しできるのですが、storyboadで作ったような表示になりません。(セルの高さが違う、ラベルが表示されないなど) グローバル変数などを使っても解決できますが、なるべく複雑にはしたくありません。 ご指摘お願いします。

  • xcodeでのiOS開発で、コードで画面遷移する時

    xcodeでのiOS開発で、コードで画面遷移する方法について質問です。 テーブルビューで、セルをタップすると呼び出されるメソッドで コードで画面遷移をさせようとしています。 しかし、画面遷移をすると遷移先の画面が真っ黒になってしまいます。 どうすればなおりますか? - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NextViewController *nvc = [[NextViewController alloc] init]; nvc.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewController:nvc animated:YES]; } ちなみに、遷移先のクラスはインポートしてあります。 StoryBoardは使っていません。

  • Xcodeでの画面遷移について

    Xcode5.0でアプリを作成しています。 アプリがバックグラウンドから再びアクティブになるときに画面遷移の処理をするために 以下の方法にてAppDelegateのapplicationDidBecomeActiveからView Controllerに処理を渡しています。 AppDelegate.m - (void)applicationDidBecomeActive:(UIApplication *)application { [[NSNotificationCenter defaultCenter] postNotificationName:@"applicationDidBecomeActive" object:nil]; } ViewController.m { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:@"applicationDidBecomeActive" object:nil]; } - (void)applicationDidBecomeActive { ViewController *View = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondView"]; [self presentModalViewController:View animated:YES]; } ViewController.mの- (void)applicationDidBecomeActiveで画面遷移の処理をしたいのですが、ViewDidAppearでは出来る画面遷移がapplicationDidBecomeActiveでは実行されない状態です。 ググって調べたところ、読み込みのタイミングが問題らしいことはなんとなく解ったのですが、 どうにかして、- (void)applicationDidBecomeActiveと同じタイミング(アプリがアクティブになったとき)で画面遷移を行う方法はありますでしょうか?

  • Xcode4のエラー(IPhoneアプリ)

    はじめまして。 IPhoneのアプリ作成に挑戦しています。 Xcode4のバージョンは 4.5.1です。 【はじめてのXcode4プログラミング】という参考書でIPhoneのカメラアプリを作る章があり、写真ライブラリから選択した画像を表示できるとのことです。 しかし、XcodeでRun(実行)すると、ViewController.mの最後2行【UIImage *originalImage =[info objectForkey:UIImagePickerControllerOriginalImage];】が赤くなり、【’dismissModalViewControllerAnimated’is deprecated: first deprecated in iOS 6.0】というエラー表示がでます。 全体のコードは下記の通りです。 ネットで調べてみましたが、解決方法がわかりません。 先に進めず困っています。 どうか解決方法を教えてください。 よろしくお願い致します。 ●ViewController.h// // ViewController.h // CameraApp // #import @interface ViewController : UIViewController - (IBAction)pressCameraButton:(id)sender; @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end ●ViewController.m // // ViewController.m // CameraApp // #import “ViewController.h” @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)pressCameraButton:(id)sender { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self presentModalViewController:picker animated:YES]; } - (void)imagePickerController:(UIImagePickerController*)Picker didFinishPickingMediaWithInfo:(NSDictionary*)info { [self dismissModalViewControllerAnimated:YES]; UIImage *originalImage = [info objectForkey:UIImagePickerControllerOriginalImage]; self.imageView.image = originalImage; } @end

  • iPhoneアプリの開発についてです。

    UINavigationControllerのルートに紐づけられたBookMarkViewControllerというビューがあります。 このBookMarkViewControllerはテーブルビューで、 (1) BookMarkViewController *nextDir = [[BookMarkViewController alloc] init]; [self.navigationController pushViewController:nextDir animated:YES]; 上記のようなコードで、次々と画面遷移していきます。 また、BookMarkViewControllerには、 (2) BookMarkViewController *move = [[BookMarkViewController alloc] init]; move.isMove = YES; UINavigationController *nav = [self.storyboard instantiateViewControllerWithIdentifier:@"BookMarkView"]; [nav setViewControllers:[NSArray arrayWithObjects:move, nil]]; [self presentViewController:nav animated:YES completion:nil]; 上記のような内容のメソッドがあり、次々と画面遷移することのできる新たなUINavigationControllerをモーダル表現で表示します。 画面遷移する前のBookMarkViewControllerでは、上記のコードでうまくモーダルがでるのですが、(1)のメソッドを実行し新たに作り遷移したBookMarkViewControllerではなぜか、 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <BookMarkViewController: 0x11822e070>.' というエラーが吐き出されうまくいきません。 (2)のメソッドで「nav」を生成した直後にnav.viewControllersをNSLogしてみたのですが、nullがかえされてしまいました。(成功した例では<BookMarkViewController ○○○>と、正常に表示されました) 誰かわかる方ご指摘お願いします。

  • 【iphoneアプリ開発】ボタン&処理の共通化

    突然の質問失礼致しますm(_ _)m ナビゲーションバーを使用したアプリを作っています。 右に「使い方」の画面へ遷移するUIBarButtonItemを配置したいと考えております。 このとき、各画面のボタンの配置、遷移したときのアクションを書けば 遷移できるのは確認できたのですが、全てのページにそれを書くのがあまり よくないような気がしています。 ボタンとボタンのアクションを共通化することは可能でしょうか? また、その場合どのファイルにどのように書くのが後々の変更等にも耐えやすいでしょうか? (例えば、「使い方」ボタンを「設定」ボタンに変更する等。。。) 実装しているボタンとボタンのアクションのソースは以下になります。 //ボタンの配置(viewDidLoad) UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithTitle:@"使い方" style:UIBarButtonItemStylePlain target:self action:@selector(howtoButtonTouched:)]; self.navigationItem.rightBarButtonItem = btn; //ボタンのをタップしたときのアクション -(void)howtoButtonTouched:(id)sender { //使い方画面へ遷移 HowtoViewController *howtoViewController = [[HowtoViewController alloc] init]; [self.navigationController pushViewController:howtoViewController animated:YES]; } どなたか、良い方法があればご教授頂けますと 大変ありがたいです。

  • テーブルビューで配列が自動消滅することについて

    xcode4.1をつかってiphoneアプリを作成しています。 テーブルビューの画面遷移時に、 可変配列NSMutableArrayに plistを読み込ませたNSMutableDictionaryの一意のキーの中身を保存し、 更に選択した行番号で呼び出した配列の中身を別ビューに渡そうとすると失敗してしまいます。 ・・自動解放されてしまっていると思うのですが、 [[[NSMutableArray alloc] init] retain]; としてもうまくいきませんでした。 どうすればうまくデータを別ビューに渡せるでしょうか。 (plistの読み込みは必須です。。) すみませんがご教授いただけますでしょうか。。。 よろしくお願いいたします。 //-------- .h------ @interface DtlVCL : UITableViewController { //別のViewからデータ受け渡し用 NSString *rcvStr; //plist一時読み込み用 NSMutableDictionary *dic; NSMutableArray *ary; } .m------------ viewDidLoad------ //各変数初期化 ary = [[[NSMutableArray alloc] init] retain]; dic = [[[NSMutableDictionary alloc] init] retain]; id path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"xxxxxxxx.plist"]; if([[NSFileManager defaultManager] fileExistsAtPath:path] == YES){ dic = [NSMutableDictionary dictionaryWithContentsOfFile:path]; }else{ NSLog(@"Dtl :ファイル読み込みエラー"); } ary = [dic objectForKey:rcvStr];//rcvStrは前ビューから取得した文字列 ------------------- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath------ ExpVCL *expvcl = [[ExpVCL alloc] initWithNibName:@"ExpVCL" bundle:nil]; //データの受け渡し expvcl.rcvNum = [indexPath row]; expvcl.rcvStr = [NSString stringWithFormat:@"%@",[ary objectAtIndex:[indexPath row]]]; [self.navigationController pushViewController:expvcl animated:YES]; [expvcl release];

  • Xcodeでマルチスレッドでなく順処理する方法

    こんにちは。 今Xcode4.2.1を使っております。 さて、今処理としてあるアプリ連携を行う処理を作っているのですが、 マルチスレッドでなく 「処理A」→「処理B」→「処理C」 と順に処理をしたいのですが、スレッド化してうまくいきません。 具体的には [self presentModalViewController: controller animated: YES];(処理A) [処理B] [処理C] : と書いた時に、処理Aがスレッドとして動くので、 処理Aが終了しないうちにB、Cがスタートしてしまいます。   1)順に処理をさせたい(マルチスレッド化しない方法)のですが、     どうやったらよいのでしょうか? もしくは   2)Aの処理がおわるまで監視&制御する(排他制御)方法はあるのでしょうか? 素人質問で申し訳ありません。 些細なことでも結構ですので 宜しくお願い致します。

  • iOSアプリ起動時にビューを移す方法

    iOSアプリ開発初心者です。 初めてアプリを起動するときに、ビューを"passtest"に移したいのですが、以下のコードを書いたんですが、動作しません。メインコントローラの.mファイル((void)viewDidLoadメソッドの中で)で書きました。 int firstvalue = 1; if (firstvalue==1) { passtest *controller = [[passtest alloc] initWithNibName:@"passtest" bundle:nil]; controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:controller animated:YES]; [controller release]; } IBActionにしてアクションをボタンに割り当てれば、問題なくビューを移せます。 起動時にどうやってビューを移すことができるのでしょうか? iOSアプリに詳しい方がいらっしゃいましたら、ご回答をよろしくお願いします。

  • viewWillAppear内での別画面表示

    iPhoneアプリ開発を勉強している者です。 少し詰まってしまった部分があるので、知恵を貸していただけるとありがたいです。 アプリを起動した際に、ログイン設定を持っているかどうかを判定して、設定を持っていれば通常の初期画面(ViewController)を表示し、持っていなければその前にログイン画面(LoginViewController)を表示する、といった動きをさせようとしています。 色々とネット上で調べてコードを書いてみましたが、うまく動作しません。 具体的には、ログイン設定を持っていない場合に、VewControllerが一瞬表示されたあと真っ黒な画面が表示されてしまいます。 Unbalanced calls to begin/end appearance transitions forというエラーメッセージが吐き出されていて、調べてみると「viewDidLoad 内で他の viewController を表示しようとした場合に出るエラー」とのことでしたが今回の件には当てはまらず原因がよくわかりません。 コードの該当部分は以下です。 /* * ログイン画面を表示する。 */ - (void) showLoginView { LoginViewController *c = [[LoginViewController alloc] init]; UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:c]; navigation.navigationBarHidden = YES; navigation.modalPresentationStyle = UIModalPresentationFormSheet; [navigation.navigationBar setBarStyle:UIBarStyleBlackOpaque]; [self presentModalViewController:navigation animated:YES]; } - (void)viewWillAppear:(BOOL)animated { if([self hasLoginSettings] == NO) { [self performSelectorInBackground:@selector(showLoginView) withObject:nil]; } } なにか、解決策などを示していただけると非常にありがたいです。 どうかよろしくお願い致します。

専門家に質問してみよう