- 締切済み
Xcodeで子のViewから親の変数を変更する
こんにちは 現在Xcodeでの作業をしています。 画面の遷移の際に現在は (親から子どもへの値を渡す場合<遷移する場合>) ViewcontrollerA *svc = [[ViewcontrollerA alloc] init]; svc->hogehoge = 1; //値などを入れる場合 [self presentModalViewController:svc animated:yes]; [self.parentViewController dissmissModalViewControllerAnimated:YES]; と値を入れているのですが、 逆に上記のAという子どもの(インスタンス内)から親の変数をいじるにはどうすればいいですか? super->parenthogehoge =1 みたいにできればいいのですが、これだとうまくいかなくて・・・。 よろしくお願い致します。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- harawo
- ベストアンサー率58% (3742/6450)
おっとっと、かんじんの「子のViewから親の変数を変更する」について、なにも触れないままでしたね。その前段階のコードを書くのに、時間を費やしてしまって、忘れてしまってました。 ChildViewController.mに、つぎのアクションメソッドを追加します。Interface Builder上で、ボタンなどに紐付けしてください。 - (IBAction)set3: (id)sender { self.parent.value = 3; } ParentViewControllerのほうで、なんらかのプロパティvalueの値を出力するコードを、適当に書いて、じっさいに値が3になっているか、確認してください。
- harawo
- ベストアンサー率58% (3742/6450)
No.1の回答の続きです。 画面遷移時のプログラムのポイントは、オブジェクトがいつ生成されるか、それとオブジェクトの参照と操作のタイミングが合うかどうか、です。ここでいうオブジェクトとは、View Controller、その上のView、それに付属しているボタンなどのコントロール、文字列や数値など、ひっくるめてです。 オブジェクトが生成され、完了する前に、そのオブジェクトを参照したり、操作しようとしても、うまくいきません。つねに、そのオブジェクトは、いつ生成されるのか、意識しながらプログラムを書く必要があります。 No.1のサンプルコード、ChildViewController.mで、データ参照の実装を、viewDidLoad:ではなく、viewDidAppear::に行ったというのは、まさにそれが理由です。おそらく0.1秒に満たない差だと思いますが、後者のメソッドが、前者より後に実行され、その間にオブジェクトの生成が進行していることがわかります。 ParentViewControllerからChildViewControllerのプロパティを参照、操作するのではなく、ChildViewControllerから、ParentViewControllerのプロパティを参照する手順をとっているのも、そういう理由です。
- harawo
- ベストアンサー率58% (3742/6450)
まず、回答に入る前に、他インスタンスから、インスタンス変数を参照するのはやめましょう。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