忍者ブログ

[PR]

2017年10月20日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

戻り先のビューへメッセージを送る

2009年02月17日
TableViewでpushViewControllerを呼び出してスクロールさせていく場合には、スクロールする前にいろいろとデータを渡してやるのに苦労することはまずありません。なぜならpushViewControllerで次のビューを表示するために使うViewControllerの参照を書いているからです。それをもとに関数を呼ぶなり変数を変更するなり好きにすれば良いのです。ここまでは当たり前な話です。

では、その逆にpopViewControllerで戻る側にデータを渡したい場合はどうでしょう。代表クラスに全部データを持たせておき、そちらを通じてやりとりする手もあります。渡したいデータは代表クラスに渡しておき、戻り先のViewControllerにあるViewWillAppearで代表クラスへデータを取りにいくようにさせれば、更新内容を反映させる事はできます。でも、プログラムが終了したら破棄するようなデータなどにもいちいち代表クラスを橋渡しに使う必要はあるのかと思う事も多々あります。かといって今表に見えているViewControllerまでの道のりが常に同じとは限らないこともあります。同じような値の設定をする場合には再利用した方が効率が良いだろうと、設定用のViewControllerが数種類の呼び出し元を持つ事もあります。では、そんな場合で直接データを渡したい時はどうするかですが、まずは以下のコードを見てください。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

[myTableView deselectRowAtIndexPath:indexPath animated:YES];

NSArray *naviArray = [self.navigationController viewControllers];

NSInteger nowIndex = [naviArray count];

id aViewController = [naviArray objectAtIndex:nowIndex-2];

if([aViewController isKindOfClass:[FTPUploadViewController class]]) {

FTPUploadViewController *controller = (FTPUploadViewController *)[naviArray
objectAtIndex:nowIndex-2];

NSString *aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"url"];

[controller setDirectoryTextFieldText:aString];

aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"username"];

[controller setUsernameTextFieldText:aString];

} else if([aViewController isKindOfClass:[FTPDownloadViewController class]]){

FTPDownloadViewController *controller = (FTPDownloadViewController *)
[naviArray
objectAtIndex:nowIndex-2];

NSString *aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"url"];

[controller setDirectoryTextFieldText:aString];

aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"username"];

[controller setUsernameTextFieldText:aString];

}

[self.navigationController popViewControllerAnimated:YES];

}


FTP用のアドレスとユーザー名の組み合わせ(Tiny3Dではこいつをブックマークと呼んでます)をテーブルでリスト表示させていて、選択されたら元の設定用のビューにデータを渡そうという部分です。FTPはダウンロードとアップロードの両方で使いますが、同じFTP用なのにわざわざ2種類のブックマークリストを持つ必要もあるまいと、どちらからも同じTableViewControllerをpushViewControllerを使って表示しています。そのため、選択後の戻り先はアップロードの設定用かダウンロードの設定用のどちらかのViewControllerになります。この場合にはnaviArrayという配列を作ってその中にnavigationControllerが持っているこれまでに通過してきたViewControllerのリストを放り込んでいます。配列はインデックス0から始まるので、countで返ってくる配列の個数から2を引いたインデックス値が、今のViewControllerの呼び出し元になります。そして呼び出し元クラスがアップロードかダウンロードかで場合分けを行い、データを変更するための関数へメッセージを送っています。この当時はまだobjc_msgSendの使い方を知らなかったためにこんなコードになっていますが、どちらでもメッセージを受け取る関数は同じなので、型キャストをせずにid値だけを得て、objc_msgSendでメッセージを送るだけで済ませてしまえば分岐する必要が無くなります。ただ、何か問題が起きた場合のデバックをする場合は上のように書いてある方がやりやすいのかもしれません。


PR
Comment
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字
Trackback
トラックバックURL: