以前、iPhoneアプリ作成のとっかかりというエントリで、画面間の値の受け渡しのことを書きました。
受け渡す相手(子)をインスタンス化して、プロパティに値を設定してしまう、という方法です。
MyViewController *myViewCon = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; myViewCon.hogehoge = @"value";
あれからだいぶ経って、上記のようにxibをコードでインスタンス化する方法から、StoryBoardを使ってFrameworkで画面遷移を作るのが主流になっています。最近iOSの勉強をサボっていて、追いつくのが大変なのですが。。
StoryBoardを使った場合、上記のコードはだいぶ違ったものになってきます。
まず、画面遷移はsegueで作成して、segueに名前をつけておきます。(segueは複数個作れるので)
単なる画面遷移ならコードを書かなくてもいいのですが、値の受け渡しの際には、子のViewControllerをインスタンス化するコードを、次のように書きます。
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ( [[segue identifier] isEqualToString:@"MySegue"] ) { ChildViewController *cvc = [segue destinationViewController]; cvc.value = self.value; // 子から親への参照用 cvc.delegate = self; } }
prepareForSegueというメソッドがポイントですね。この中で、子のインスタンスに値を渡すことができます。
さて、子から親へ受け渡しするのはちょっと面倒で、delegateを使用します。
上記メソッド内で、子のdelegateを親、という設定をしました。
そして、子から親のメソッドを呼び出すことによって、値を受け渡すわけです。
delegateの設定自体はデリゲートを自作クラスに実装するでわかりやすく解説されています。
問題は、親のメソッドを呼び出すタイミングです。親から子を呼び出す際には、prepareForSegueメソッドに書けばよかったですが、子から親へ遷移する場合は、画面間でのデータの受け渡しに付いてを参考にさせてもらうと、viewWillDisappear時に行います。
-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.delegate getValueMethod:value]; }
iOSはバージョンが上がるたびに作法がどんどん変わるので、常にウオッチしておかないとついていけなくなりますね。