2011年5月12日木曜日

UITableViewController(その1 スタイル)

UITableViewControllerは恐らく一番使うのではないでしょうか。iPhoneアプリではリストで何かを表示するという要求は多いのではないかと思います。

UITableViewControllerにはスタイルがあります。
標準的なリスト表示スタイルと設定画面でよく見かける設定項目毎にグループ化されて見えるスタイルです。

標準的なスタイル


グループスタイル

このような画面を作成してみます。
まずは、クラスの定義ですが、手順はUIViewControllerと同じようにして、クラスを作成します。




UITableViewContorollerは2つの以下のプロトコルを採用しており、その動作をプロトコルの実装を行うことで動作させています。

プロトコル意味
UITableViewDataSourceテーブルのデータモデルを表す
UITableViewDelegateテーブルの動作を表現する

な感じでしょうか。詳細はそれぞれのリファレンスを参照頂くとして、最低限必要なメソッドはスケルトンにて既に実装されていますので、そのコードを修正していきます。
また、データは配列で持つこととします。

ヘッダはこんな感じでデータ格納用のインスタンス変数を定義しておきます。
@interface MyTableViewController : UITableViewController {
    //データ格納用配列
    NSArray *arrayData;
}
@end

データの初期化は初期化メソッドにでも定義しておきます。

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        //データの初期化
        arrayData = [NSArray arrayWithObjects:@"data1", @"data2", @"data3", @"data4", nil];
    }
    return self;
}

データの解放コードも忘れずに。

- (void)dealloc
{
 //データの解放
    [arrayData release];
    [super dealloc];
}

UITableViewDataSourceプロトコルの採用メソッド定義

セクションの数を返す。
今回はセクションを一つにしたので、1を返却するのみになります。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

セクション内の行数を返す。
作成したデータの個数を返すようにします。今回はセクションが一つなので、引数にあるsectionは参照していませんが、
セクションが複数ある場合はセクションに対応したデータの個数を返却するように実装する必要があります。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [arrayData count];
}

行(セル)の内容を返す。
セクション、行に対応するデータが必要になった際に呼び出されます。
引数のindexPathにはセクションと行NOの情報が格納されています。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 //内部的なID。IDとして文字列でセクションNOと行NOを設定しています。
 //別に各行でユニークなら何でも良いはずです。
    NSString *CellIdentifier = [NSString stringWithFormat:@"section : %d, row no : %d", indexPath.section, indexPath.row];
    
    //一度表示した行(セル)は内部でキャッシュしてくれるので、キャッシュが存在すればそれを使用し、なければ生成するイメージ。
    //殆どスケルトンのコードです。
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        
        //セルのテキストとして、データの内容とセクションと行数を表示させます。
        cell.textLabel.text = [NSString stringWithFormat:@"%@ : %@", [arrayData objectAtIndex:indexPath.row], CellIdentifier];
        //ついでにフォントも指定してみる。
        cell.textLabel.font = [UIFont fontWithName:@"Arial" size:12.0];
    }
    // Configure the cell...
    return cell;
}

ヘッダーとフッターの内容を返す。
これらのメソッドはスケルトンには含まれていませんでしたので、自分で定義して実装しました。

//ヘッダー
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    //セクションが一つなので、そのまま返却していますが、セクションが複数ある場合はセクションに対応する値を
    //返却する必要があります。
    return @"これはheaderです。";
}

//フッター
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    //セクションが一つなので、そのまま返却していますが、セクションが複数ある場合はセクションに対応する値を
    //返却する必要があります。
    return @"これはfooterです。";
}


UITableViewDelegateプロトコルの採用メソッド定義

セルが選択された時の処理を書く。
スケルトンには以下の処理が書かれています。今回は何もしないのでそのまま放置。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#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];
     */
}

作成したTableViewControllerのインスタンス生成。

AppDelegateクラスのdidFinishLaunchingWithOptionsメソッドに記述するイメージです。

標準的なスタイルの場合
myTableViewController = [[MyTableViewController alloc] initWithStyle:UITableViewStylePlain];
//add to view.
[_window addSubview:myTableViewController.view];

グループスタイルの場合
myTableViewController = [[MyTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
//add to view.
[_window addSubview:myTableViewController.view];

0 件のコメント :

コメントを投稿