このページは「iPhoneプログラミング入門」(工学社刊、ISBN 978-4-7775-1541-7)を読んで、もっと先へ進んでみたいと思った人への説明です。

<-前へ
「次の一歩」一覧へ

最も簡単なナビゲーションの作り方5

GreenViewControllerとBlueViewControllerを作成する/h2> RedViewControllerと全く同じように、GreenViewControllerとBlueViewControllerを作成します。それぞれ、インターフェイス・ビルダー上で、背景色を緑及び青にします。

RootViewController.mを編集

RootViewController.mのメソッドtableView:didSelectRowAtIndexPath: を、修正します。

Redという文字列からRedViewControllerクラスを作りたい

この修正で大事なのは、「RedViewController」という決まった名前のクラスを使うのではなく、"Red", "Green"そして"Blue"という文字列に応じて、それを名前に含めたクラスをその場で指定することです。
以下の部分を直さなければなりません。
RedViewController *nextViewController = [[RedViewController alloc] ......

指定したセルの値から文字列を得る

まず、セルを指定して得た文字列から、"ナニナニViewController"という文字列を作らなければなりません。これは、リスト9のようにします。
リスト9 セルを指定して得た文字列にViewControllerという文字列をくっつける
NSString *controllerName=
  [[NSString alloc] initWithFormat: @"%@ViewController", [theList objectAtIndex:indexPath.row]];
本書では、数値を文字列にするのに%dという記号を使いました。これは、同じように「%@のところには文字列が入る」という、文字列作成の方法です。

NSClassFromStringという「マクロ」を使う

指定した文字列からその名前のクラスを呼び出すには「NSClassFromString」という「マクロ」を用います。ちゃんと存在するクラスでなければ、nilが返ります。 ここでは、変数controllerNameが指す文字列から、その名前のクラスを呼び出します。これで、controllerNameの中身がGreenViewControllerなら、GreenViewControllerクラスが指定されることになります。そこで、以下のようにこれにallocメソッドを使えば、そのクラスのオブジェクトが作成されるわけです。
...[NSClassFromString(controllerName) alloc] ...

「親クラス」で「子クラス」どうしを共通化

しかし、作成されるオブジェクトnextViewControllerのクラスを、プログラム中でどう書き表せばよいでしょうか。場合によってRedViewControllerだったりBlueViewControllerだったりするわけですから....。 それにはよい方法があります。RedViewControllerもBlueViewControllerも、すべてUIViewControllerクラスを継承しています。そこで、継承元のUIViewControllerをオブジェクトのクラス名として使えば、「大は小を兼ねる」で、文法的に整合します。
UIViewController *nextViewController =....

nextViewController生成の式の完成

以上、RedViewControllerクラスのオブジェクトに限定されていたnextViewControllerの生成法を、リスト10のように書き換えれば、指定したセルの値に対応する名前のビューコントローラのオブジェクトにすることができます。これで、他のビューにも移動できるようになるのです。nextViewControllerを用いたコードは、この後は変更しなくてOKです。
リスト10 他のビューにも移動できるようにする修正コード UIViewController *nextViewController = [[NSClassFromString(controllerName) alloc] initWithNibName:controllerName bundle:nil];

controllerNameをrelease

最後に忘れてはいけないことがあります。controllerNameにreleaseメソッドを用います。これは、メソッドの中で作成した文字列オブジェクトですから、同じメソッドの最後に書きます。先に作成したオブジェクトほど後に解放するようにすると、安心でしょう。
リスト11 メソッド中で作成したオブジェクトは、メソッド中で解放する [controllerName release];

GreenViewControllerとかはimportしなくていいの?

なんと、いいみたいです。
RedViewControllerというクラスをプログラム中で直接指定していたときは、そのRedViewControllerに関する情報をコンパイラに教えるためにimport宣言をする必要がありました。しかし、リスト10のような方法でクラスを取得するのであれば、import宣言は必要ないようです。
これは筆者も予想外のことで驚いています。もし、コンパイルエラーが起きるようでしたら、必要なクラスをインポートしてみてください。
ビルド、実行してみると、テーブルからBlueを選んだときには青いビューになるでしょう。Backボタンでテーブルに戻るなど、楽しんでください。
おつかれさまでした。「次の1歩」のページへ戻ります