前回の第1案、Interface BuilderでSecondViewControllerのOutletとしてUITableView、UITextView、UIImageViewを設定する方法をやりますよん。

 このSecondViewControllerは「iPhoneアプリ開発、その(155)」で作った投稿詳細表示ページに該当するView用のControllerということになります。

$テン・シー・シー-3

 で、まずは以下のような画面とうい事でInterface BuiderでViewを準備したわけですが、この各ViewにSecondViewControllerがアクセスする方法としてXcodeのクラス定義でIBOutletというキーワードを使うんですな。

$テン・シー・シー-1

 とにもかくにもXcodeでSecondViewControllerの作成~。
 ファイル>新規ファイル...メニューを選んでワントゥスリー。

$テン・シー・シー-2

 オプションに同時にXIBファイル作るってのがありますね~。今回はすでにSecondView.xibがあるんで作らないけど、新規に作る場合は重宝するかもね。

$テン・シー・シー-3

 名前はSecondViewControllerじゃなくDetailViewControllerとしました。
 xibと同じ名前にするのが紛らわしくなくていいんだけど、今回は別名でも問題ないという事を示すためにあえて別名にしてみます。

 で、今回Viewの各パーツにアクセスするためにDetailViewController.hに変数として以下の3つを用意。いつもと違うのはIBOutletの存在。

@interface DetailViewController : UIViewController {
IBOutlet UIImageView* imageView;
IBOutlet UITextView* commentView;
IBOutlet UITableView* sugestionTableView;
}

 ちなみにIBOutletを選択してコンテキストメニューで「定義にジャンプ」を選び定義位置にジャンプするとIBOutletは

#ifndef IBOutlet
#define IBOutlet
#endif

 というふうに定義されててIBAction同様、プログラム的にはまったく意味がないってのがわかるっすよ。こいつはInterface Builderに知らせるためだけに用意された定義ってわけです。
 
 書き終わったら、いったん保存してSecondView.xibダブルクリックでInterface Builderを起動~。
 SecondView.xibウィンドウのFile's Owner(このxibファイルをinitWithNibName:で読み込んで利用するインスタンスがファイルの持ち主ってことになる)を選んでInspectorウィンドウのIdentityタブを選ぶと

Class UIViewController

 となってるんで、このコンボボックスからDetailViewController(ちゃんと出るんですな~)を選びます。

$テン・シー・シー-4

 そうすると、さっきXcodeでDetailViewControllerに定義したIBOutlet変数があらわれるわけですわ。

$テン・シー・シー-5

 あとは、InspectorウィンドウでConnectionsタブをクリックして出てきたOutletの右にある○をドラッグして結びつけたいViewにドロップする。

$テン・シー・シー-6
あ、わんとぅすり~

 ここらへん昔のInterface Builderと違ってかなり明示的になってますね。

$テン・シー・シー-7

 で、3つの変数すべて結び終わったらInterface Builderに用はないので保存して終了。
 Xcodeに戻ってDetailViewControllerの実装に入るわけです。
 まずはDetailViewController.mの

viewDidLoad

 のコメントを外して

- (void)viewDidLoad {
[super viewDidLoad];
commentView.text = @"お試し";
}

 と実装。うりゃっと実行。

ぐあっ!

 死にました。
 そーなんだよ、FirstController側の呼び出し、UIViewControllerのままじゃんよ。なんてバカだ。DetailViewControllerに修正せんと。

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath
{
DetailViewController* ctl = [[DetailViewController alloc]
initWithNibName:@"SecondView" bundle:nil];
[self.navigationController pushViewController:ctl animated:YES];
[ctl release];
}

 こうなんだよ。こう。#import "DetailViewController.h"も忘れんようにね。
 うりゃ、ビルドして実行。

$テン・シー・シー-8
でた、アクセス成功

 調子のりお。
 このままDetailViewControllerにUITableViewDataSourceを継承させてテーブルの内容部も設定したれぃ!

@interface DetailViewController : UIViewController<UITableViewDelegate,
UITableViewDataSource
> {

 でも、めんどくさいんで実装するのは以下の3メソッドだけね。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return 10;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"DetailCell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [NSString
stringWithFormat:@"提案 %d", indexPath.row];
return cell;
}

 あとはviewDidLoadでsugestionTableViewのdataSourceとしてselfを設定でおしまい。

- (void)viewDidLoad {
[super viewDidLoad];
commentView.text = @"お試し";
sugestionTableView.dataSource = self;
}

 うりゃっと実行。

$テン・シー・シー-9
でた

 おっしゃあ、景気づけに画像も貼付けてみますか~。とこいつはFirstViewController側のtableView:didSelectRowAtIndexPath:メソッドを拡張して

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath
{
DetailViewController* ctl = [[DetailViewController alloc]
initWithNibName:@"SecondView" bundle:nil];
UITableViewCell* cell = [tableView
cellForRowAtIndexPath:newIndexPath];
UIImageView* imageview = (UIImageView*)[cell viewWithTag:tag_Photo];
ctl.imageView.image = imageview.image;
[self.navigationController pushViewController:ctl animated:YES];
[ctl release];
}

 うりゃっと実行。

 変化無し...

 デバッガで止めて確認。ctl.imageView.imageがnilでした。
 ですね。
 initWithNibNameの段階じゃViewは作られてないんですな。
 ま、ここらへんどうするかと、ちょっと気になるメソッド

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

 も含めて以下次回!

------------
サンプルプロジェクト:konohana_test4.zip


ゲット!
treasure