MasterとDetail

教本にあった、リスト表示の結果からタップすると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];

ふむ。改めて文にすると理解が深まるなぁ。