CoreData: Master-Detail の detail 処理について

CoreData を使用するテンプレートで Master-Detail があり、とっかかりは重宝するのですが、立て込んだことをしようとすると色々わからないことが多い。

今日分かったのは、Detail の record 編集について。

Master から Detail の ViewController に移動しますが、そこはつまり Master の詳細画面な訳で、Detail に record を追加したり、あるいは編集したいという時のために Detail 用の ViewController が必要になります。言ってみれば Detail-Detail ということになるでしょうか。テンプレートの名称からして誤解が生まれそうなんですが、Master の 1 record を編集するための名称として Detail としている訳で、1 : N の N レコード一つ一つを編集する画面ではないということになります。

そんな構造が分かっているとしても、Detail に設置した tableView のレコードを追加する部分までは、Master-Detail のテンプレートからそれなりに応用が効くと思いますが、追加済みの N レコードを編集するにはどうすればよいか、はたと悩んでしまいました。こう言ったことに言及している記事がないので、オレオレですが書いておこうと思います。

まず、tableView に表示されているレコードが選択された時に呼ばれる delegate method はこれ:

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

この method 内で、選択された cell をグローバル変数に入れておきます。次に、

performSegueWithIdentifier

で、強制的に prepareForSegue を呼びます。prepareForSegue では、遷移先の Class の property に値をセットしてやります。こんな感じですかね。

    InputDetail* controller = (InputDetail *)[segue destinationViewController];

    [controller setDetailDetail:selectedCell];

書いていませんでしたが、遷移先にはあらかじめ対応する property を設定しておく必要があります。上記の例では detailDetail という property になります(property を新設すると勝手に method が作られている、、というか、もともと Objective-C で property をそう定義してあります)。ところで、prepareForSegue で遷移するには理由があり、遷移先の ViewController (のポインタ)を取り出し易いのです。キャストしないと警告が出る点が嫌なんですが、他に書き方がわからないのと、キャストする都合、汎用的な書き方じゃないよね(他のプログラムにそのまま使い回せないね)というのが難点でしょうか。

遷移先では、property detailDetail に値があるかどうかで挙動を変えるようにします。書き方は、DetailViewController の template のが参考になります。

 最後に、DetailDetail から Detail に戻ってきたときに呼ばれる method は次の通り。

- (IBAction) firstViewReturnActionForSegue:(UIStoryboardSegue *)segue

このメソッドでは、グローバル変数にセットした値をクリアしておく必要があります。なぜなら、record を追加しようとしているときも、選択したときも結局は prepareForSegue が呼ばれるので、追加したときもセルを選択した時のような挙動になるためです。

という訳で、できたのでよかったんですが、こういう解説があまりないのが CoreData の辛いところでしょうか・・・