今回の記事は以下の記事を既読の方を想定しています。
今回学ぶこと:
- Navigation-Based Application の新規作成
- フルーツClassのオブジェクト作成
- NSArray 配列を作成し、書き込む
- 新規ビューの追加
- viewとコードを接続する
- オブジェクトのデータをUITableViewに書き込む
- viewを遷移させ、選択された行に基づくデータを表示させる
フルーツを表現するのに必要なプロパティを作成しました。 見慣れない一行がありますね。#import <Foundation/Foundation.h>
@interface Fruit : NSObject {
NSString *name;
NSString *description;
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *description;
-(id)initWithName(NSString*)n description:(NSString *)desc;
@end
この行は関数を定義しています。この関数は、果物のオブジェクトを初期化するために呼び出されます。 すべてのNSobjectはinitメソッドを持っていますが、独自に設定したい時は、オブジェクトが作成される時に、名前や詳細情報を渡すことが出来ます。 Fruit.m を開き、以下のように編集してください。-(id)initWithName(NSString*)n description:(NSString *)desc;
ここでは、initWithNameメソッドを実装しています。このメソッドに渡される引数の名前と詳細情報をローカルコピーに設定しています。 ここで重要なのは、「return self」の行です。これは、コンストラクタとしてこのメソッドを使用するために非常に重要です。こうすることで、この関数が、新たに作成された果物オブジェクトのインスタンスを返すことができるようになります。(?) 次は、メインviewのタイトルの設定を行います。この設定はview間を移動し、戻るボタンを設置するためには、必ず指定しなければいけません。 RootViewController.m を開き、viewDidLoadメソッドを以下のように編集します。#import “Fruit.h”
@implementation Fruit
@synthesize name,description;
-(id)initWithName:(NSString*)n description:(NSString*)desc {
self.name = n;
self.description = desc;
return self;
}
@end
これで、RootViewControllerオブジェクトのタイトルが「果物リスト」と設定されました。#import 文と @synthesize 文の追加を忘れないようにしてください。 次に、果物オブジェクトの配列を作成します。FruitAppDelegate.h を開き、以下のコードを追加します。#import “RootViewController.h”
#import “FruitAppDelegate.h”
#import “Fruit.h”
@implementation RootViewController
@synthesize fruitView;
#pragma mark –
#pragma mark View lifecycle
– (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.title = @”果物リスト“;
}
ここで加えているすべてが、NSMutableArrayのプロパティです。 NSArrayではなく、NSMutableArrayを使ったのは、後者の方がより柔軟ないくつかのメソッドを持っているからです。 FruitAppDelegate.m を開き、@synthesize 行を追加します。 これにより、他のオブジェクトは、果物の配列にアクセスできるようになります。また、Fruit.hのimport文を含めるようにしてください。#import <UIKit/UIKit.h>
@interface FruitAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
NSMutableArray *fruits;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSMutableArray *fruits;
@end
#import “FruitAppDelegate.h”
#import “RootViewController.h”
#import “Fruit.h”
@implementation FruitAppDelegate
@synthesize window;
@synthesize navigationController;
@synthesize fruits;
– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
Fruit *apple = [[Fruit alloc] initWithName:@”りんご“ description:@”赤くて美味しい“];
Fruit *orange = [[Fruit alloc] initWithName:@”オレンジ“ description:@”新鮮なオレンジジュースが出来ます“];
Fruit *melon = [[Fruit alloc] initWithName:@”メロン“ description:@”大きくて、子供たちにも大人気“];
self.fruits = [[NSMutableArray alloc] initWithObjects:apple,orange,melon,nil];
// Override point for customization after application launch.
// Add the navigation controller’s view to the window and display.
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
self.fruits = [[NSMutableArray alloc]initWithObjects:apple,orange,melon,nil];
FruitViewController.m を開き、@implementation行の下に追加します。これで fruitDescription プロパティにゲッター&セッターメソッドを作成します。#import <UIKit/UIKit.h>
@interface FruitViewController : UIViewController {
IBOutlet UITextView *fruitDescription;
}
@property(nonatomic,retain) IBOutlet UITextView *fruitDescription;
@end
FruitViewController.xib をダブルクリックし、Interface Builderを起動します。先ほど作成したFruitViewControllerクラスとviewを関連づけます。 File’s Ownerオブジェクトをクリックしてください。 Identity Inspector から下図のように設定します。 Interface Builder の最後の作業は、UITextViewを接続することです。 File’s Ownerオブジェクトを右クリックし、下図のようにviewウインドウ上のUITextViewとfruitDescriptionを接続します。 同様にしてview をFruitViewController.xibとタイトル表示されているウインドウ内のviewを接続します。(下図参照) File’s OwnerオブジェクトのTools -> Connection Inspector が下図のようになっていれば成功です。 Interface Builderを閉じます。 次にやるべきことは、新しいview(フルーツがクリックされた時に遷移される画面)にプロパティを作成します。 RootViewController.h を開き、以下のように編集します。@synthesize fruitDescription;
fruitViewController のプロパティを作成しました。#import 文が追加されていることにも注意してください。これにより、FruitViewController のインスタンスが作成可能になります。 次にRootViewController.m を開き、numberOfRowsInSection を探し、以下のように編集します。このメソッドは、UITableViewがいくつの行を表示するかを指定します。今回のケースでは配列の数だけ行を表示します。#import <UIKit/UIKit.h>
#import “FruitViewController.h”
@interface RootViewController : UITableViewController {
FruitViewController *fruitView;
}
@property(nonatomic,retain)FruitViewController *fruitView;
@end
FruitAppDelegate から始まる行は、アプリケーションのappDelegateへのアクセスが出来るように設定しています。 デリゲートにアクセスすることで、fruitsのcountプロパティが返されます。(?) The first line allows us to gain access to the appDelegate of our application. This is where we defined the fruit array. Once we have access to the delegate the count property of the fruit gets returned. 次に、cellForRowAtIndexPath を探し、以下のコードを追加します。// Customize the number of rows in the table view.
– (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
FruitAppDelegate *appDelegate = (FruitAppDelegate *)[[UIApplication sharedApplication] delegate];
return appDelegate.fruits.count;
}
“FruitAppDelegate *appDelegate…”の行は、fruit array で宣言したappDelegateオブジェクトへのアクセスが出来るようにしています。その次の行は、フルーツ配列のobjectAtIndex メソッドを呼び出しています。 我々が使用するインデックスはindexPath.rowを介してアクセスすることができます。これはUITableViewの各行を表す整数値です。 最後にセルのsetTextメソッドを呼び、指定されたインデックスにある各フルーツオブジェクトの名称を表示します。 最後のステップです。 私たちはUITableView内のどの行が選択されたかを検出します。 didSelectRow を探し、以下のように編集してください。– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @”Cell”;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
FruitAppDelegate *appDelegate = (FruitAppDelegate *)[[UIApplication sharedApplication] delegate];
Fruit *f = (Fruit *) [appDelegate.f[ objectAtIndex:indexPath.row];
[cell.textLabel setText:f.name];
// Configure the cell.
return cell;
}
このメソッドは、ユーザーがUITableView上のセルをタップするたびに呼び出されます。indexPath パラメータは、ユーザーがクリックしたセル番号を表すrowというプロパティを持っています。 最初のラインはデリゲートへのアクセスを可能にしています。 次の行は、選択されたフルーツオブジェクトのコピーを作成するように設定しています。 The next line indexes into the fruits array and makes a copy of the selected fruit object. ifで始まるセクションは、viewController が初期化されていなければ、初期化するように設定しています。 initWithNibName に渡す名前は、xibファイル名と一致していなければなりません。今回はFruitViewControllerです。 その次の行は、 Following this line is the line that pushes the viewController on to the navigationController stack. This causes the view to transition to the new view. 最後の2行は、新しいviewにフルーツの情報を渡しています。 まず、viewのタイトルにフルーツの名称を渡し、フルーツの詳細情報をdescriptionに設定しています。 以上で今回のチュートリアルは完了です。 以下の画像のように最初の画面では、フルーツリストが表示され、名称をクリックすれば、フルーツの詳細情報が表示され、タイトルがフルーツ名になったviewが表示されます。– (void)tableView🙁UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@”<#Nib name#>” bundle:nil];
// …
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
FruitAppDelegate *appDelegate = (FruitAppDelegate *) [[UIApplication sharedApplication] delegate];
Fruit *fruit = (Fruit *)[appDelegate.fruits objectAtIndex:indexPath.row];
if(self.fruitView == nil){
FruitViewController *viewController = [[FruitViewController alloc] initWithNibName:@”FruitViewController” bundle:[NSBundle mainBundle]];
self.fruitView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.fruitView animated:YES];
self.fruitView.title = [fruit name];
[self.fruitView.fruitDescription setText:[fruit description]];
}
↑起動直後の画面
↑メロンをクリックした後の画面
この投稿へのコメント