教本にあった、リスト表示の結果からタップするとURLを呼び出す構造のアプリであるが、以下の作りになっていた。
うん。実際の遷移はUI任せってあたり要注意っぽいな。
例題は当然の事ながらサンプルデータのセットなども入っていたので、そこからこの、Master・Detail間の受け渡し部分のみを抽出してみたい。
まず、master側。機能はコメントの通り。
@interface testappMasterViewController () { NSMutableArray *_objects; NSArray * tableDataList; } : (中略) : // 選択されたセルのURLデータを遷移する際にセットする。 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showDetail"]) { // 選択された行を調べる(どこが選択されたか?) NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; // セクションのデータを取り出す(tableDataListの同じ場所の情報を取り出す) NSDictionary *theSection = tableDataList[indexPath.section]; // セクションのセルの配列を取り出す(sectionの中身は配列で収納されている) NSArray *theData = theSection[@"data"]; // 指定行のセルを取り出す(選択した行(row)のデータを渡す) NSDictionary *theCell = theData[indexPath.row]; // セルからURLを取り出す(データにあるURLを読み出す) NSString *url = theCell[@"url"]; // 移動先のシーンのビューコントローラに setDetailItem: メソッドを送る [[segue destinationViewController] setDetailItem:url]; } }
tabledataListは内部的に定義された配列で、中にはテキストとURLがセットになった情報が配列で含まれている。その情報は同じ並びでmaster側のUIにも表示されている(ただしURLはセットされていない)。
リストの一部をタップすると画面遷移が起きるが、その前にまず、それが何番目(indexPath)かのデータを使ってtableDataListの元データを呼び出す。そして元データに含まれるURLを setDetailItem メソッドに付加し、おそらく遷移前に送り出す、というわけだ。
で、受け側ではこうなる。
- (void)setDetailItem:(id)newDetailItem { if (_detailItem != newDetailItem) { _detailItem = newDetailItem; // Update the view. [self configureView]; } if (self.masterPopoverController != nil) { [self.masterPopoverController dismissPopoverAnimated:YES]; } } // View制御 // Webアドレスを受け取っているので、これを表示する。 - (void)configureView { if (self.detailItem) { // URLオブジェクトを作る NSURL *url = [NSURL URLWithString:self.detailItem]; // URLリクエストを作る NSURLRequest *urlreq = [NSURLRequest requestWithURL:url]; // WebビューにWebページを読み込む。 [_myWebView loadRequest:urlreq]; } }
setDefaultItemメソッドをmasterから受け取ったので内容を見る。現状のdefaultItemと異なっていると判断されれば、これを最新の defaultItem として設定したうえで configureView を呼び出す。
configureView が呼ばれた時点でdefaultitemは新しいものに変わっているので、これを元にURLオブジェクトを作成、さらにURLリクエストを作成して WebView に受け渡するこれによりwebViewはリクエストされたURLを読み込み、表示する。
なお、configureViewを以下のように書き換えると外部ブラウザの呼び出しになる。
NSURL *url = [NSURL URLWithString:self.defaultItem]; UIApplication *app = [UIApplication sharedApplication]; [app openURL:url];
ふむ。改めて文にすると理解が深まるなぁ。