[iOS] UINib を使ったカスタム UITableViewCell の作り方

2011年5月22日日曜日 | Published in | 2 コメント

このエントリーをはてなブックマークに追加

2011-06-09 追記 UITableViewCell の Identifier 設定を忘れてたので追記しました。

UINib を使うと簡単に Nib で定義した UITableViewCell が使える。
今回のサンプル:


[関連] Cocoaの日々: [iOS] UINib を使ったカスタム UITableViewCell の作り方(その2)ボタンの処理


実装


まず CustomCell.xib を作る。

ここで表示したいセルのデザインを行う。UITableViewCell のクラスに "CustomCell" を指定しておく。

(2011-06-09 追記)
Identifier には "CustomCell" を設定しておく。この文字列は自由に付けられるがソースコード上の該当箇所と一致させておく。設定しないとセルの再利用が行われない。


次に CustomCell クラスの実装(*.m/*.h)を作成する。こんな感じ。
CustomCell.h
@interface CustomCell : UITableViewCell {
    
}
@property (nonatomic, retain) IBOutlet UILabel* nameLabel;
@property (nonatomic, retain) IBOutlet UILabel* dateLabel;
@property (nonatomic, retain) IBOutlet UILabel* descLabel;
@property (nonatomic, retain) IBOutlet UIImageView* imageView;

@end

CustomCell.m
@implementation CustomCell
@synthesize nameLabel;
@synthesize dateLabel;
@synthesize descLabel;
@synthesize imageView;

- (void)dealloc
{
    self.nameLabel = nil;
    self.dateLabel = nil;
    self.descLabel = nil;
    self.imageView = nil;
    [super dealloc];
}

@end
今回は特別な実装はやらないので単にプロパティ値のプレースホルダとして働く。

再び xib ファイルへ戻り、アウトレットの接続を行う。

セルの準備ができたら今度は UITableView の Datasource/Delegate の実装。

RootViewController.m
#define CUSTOM_CELL_NIB @"CustomCell"

- (UITableViewCell *)tableView:(UITableView *)tableView
   cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell* cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CUSTOM_CELL_NIB];
    if (cell == nil) {
        UINib* nib = [UINib nibWithNibName:CUSTOM_CELL_NIB bundle:nil];
        NSArray* array = [nib instantiateWithOwner:nil options:nil];
        cell = [array objectAtIndex:0];
    }

    // Configure the cell.
    int r = rand();
    cell.nameLabel.text = [NSString stringWithFormat:@"NAME-%d", r];
    cell.dateLabel.text = [[NSDate dateWithTimeIntervalSince1970:r] description];
    cell.descLabel.text = @"Permission is hereby granted, free of charge, to any
 person obtaining a copy of this software and associated documentation files ....";
    cell.imageView.image = [UIImage imageNamed:
       [NSString stringWithFormat:@"image%02ds.jpg", (r%8)+1]];
    NSLog(@"%@", [NSString stringWithFormat:@"image%02ds.jpg", (r%8)+1]);
    return cell;
}
ポイントは UINib を使っているところ。
UINib* nib = [UINib nibWithNibName:CUSTOM_CELL_NIB bundle:nil];
        NSArray* array = [nib instantiateWithOwner:nil options:nil];
        cell = [array objectAtIndex:0];
nibwithNibName:bundle: で xib ファイルを読み込み、instantiateWithOwner:options: でインスタンス化する。この時、owner は使わないので指定しない(nil)。今回の用途ではこれでも問題ない。CustomCell クラスのインスタンスを得るのには決め打ちで objectAtIndex:0 としている。もし xib に複数のトップレベルオブジェクトが存在する場合は区別する必要がある。なお UINib は xib ファイルをキャッシュするので繰り返し使っても読み込み自体は大きなオーバーヘッドにならない。以前のカスタムセル作成には UIViewController を使った方法があったが、それに比べると余計なインスタンス(UIViewController)を作らず、キャッシュも効くのでこちらのほうが軽量だと思われる。

なお CustomCell の高さは通常よりも大きくしてあるのでデリゲートを実装して置く必要がある。
- (void)viewDidLoad
{
    self.title = @"Custom Cell Sample";
    
    // calc height of custom cell
    UINib* nib = [UINib nibWithNibName:CUSTOM_CELL_NIB bundle:nil];
    NSArray* array = [nib instantiateWithOwner:nil options:nil];
    CustomCell* cell = [array objectAtIndex:0];
    cellHeight_ = cell.frame.size.height;
    [super viewDidLoad];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return cellHeight_;
}
今回は viewDidLoad でセルの高さをメンバ変数へ取っておく方法をとった。あらかじめセルの高さが固定であればソースコード上に直接数値を指定して返しても良い。


ソースコード


GitHub からどうぞ。
CustomCellSample at 2011-06-09 from xcatsan/iOS-Sample-Code - GitHub


関連情報


カスタムセルシリーズ

Cocoaの日々: [iOS] UINib を使ったカスタム UITableViewCell の作り方(その2)ボタンの処理

Cocoaの日々: [iOS] UINib を使ったカスタム UITableViewCell の作り方(その3)ボタンの処理[改良版]

スライド実装

Twitter公式アプリなどで実装されているセルのスライドアニメーションの実装など。
Cocoaの日々: [iOS] UITableView でセルをスワイプするとスライドするユーザインタフェースを実装

Responses

  1. 匿名
    2011年8月25日 15:33

    こういうようなエラーができました

    *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key nameLabel.'

  2. 匿名
    2011年8月25日 15:33

    こういうようなエラーができました

    *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key nameLabel.'

  3. xcatsan says:
    2011年8月31日 23:52

    こんばんは。情報どうも。
    ソースコードをダウンロードしてビルドしてみたのですがこのエラーは出ませんでした。
    https://github.com/xcatsan/iOS-Sample-Code/tree/2011-06-09/CustomCellSample
    どのソースコードで出ていましたか?

  4. xcatsan says:
    2011年8月31日 23:52

    こんばんは。情報どうも。
    ソースコードをダウンロードしてビルドしてみたのですがこのエラーは出ませんでした。
    https://github.com/xcatsan/iOS-Sample-Code/tree/2011-06-09/CustomCellSample
    どのソースコードで出ていましたか?

Leave a Response

人気の投稿(過去 30日間)