[XCode4][UIKit]UITableVieCellをオリジナルのXibを使用して表示する

ここに凄くシンプルな方法が載っていたのでまとめ。
http://stackoverflow.com/で載っていたサンプル

用意するもの

  • Cell.h
  • Cell.m
  • Cell.xib
  • MasterViewController.h
  • MasterViewController.m

前提として・・・

Cellは基本的に表示してる領域+前後いくつか分のViewしか持たないのでCellそのものにデータ保持をさせるのは危険。

やっていること

独立したUITableViewCellクラス専用に1つのXibを持たせる。
Cell自身がXibを呼び出すので、他のサイトで載っているようなController側が保持するやりかたのように複雑風にならない。

Cell.h

#import 

@interface Cell : UITableViewCell
{
    NSNumber* num_;
@private
   IBOutlet UILabel* label1_;
   IBOutlet UILabel* label2_;
   IBOutlet UIImageView* icon_;
}
@property (nonatomic,strong) UILabel* label1;
@property (nonatomic,strong) UILabel* label2;
@property (nonatomic,strong) UIImageView* icon;

+ (Cell*)cellFromNibNamed:(NSString *)nibName;
@end

Cell.m

#import "Cell.h"
@implementation Cell
@synthesize label1 = label1_;
@synthesize label2 = label2_;
@synthesize icon = icon_;

+ (Cell *)cellFromNibNamed:(NSString *)nibName {
    NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:NULL];
    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    Cell *customCell = nil;
    NSObject* nibItem = nil;
    while ((nibItem = [nibEnumerator nextObject]) != nil) {
        if ([nibItem isKindOfClass:[Cell class]]) {
            customCell = (Cell *)nibItem;
            break; // we have a winner
        }
    }
    return customCell;
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    NSLog(@"%s",__func__);
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

+ (Cell *)cellFromNibNamed:(NSString *)nibName について

このクラスメソッドでは何でも格納ObjectNSArray型のnibContentsにXibを読み込んで格納し、列挙型NSEnumeratorを生成。
Xib内に独自Cell用のnibがあったら返してもらい、それを以てCellとし、列挙を離脱。
最後にCellを返して終了する、という流れ。

MasteViewController.m

セルの生成

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    cell = [tableView dequeueReusableCellWithIdentifier:@"orgCell"];
    if (cell == nil) {
        cell = (Cell *)[Cell cellFromNibNamed:@"Cell"];
        cell.label1.text = @"test";
    }
    return cell;
}

ここでは先のCellで定義したNibを読み込んでViewを生成するクラスメソッドを呼び出して格納している。
label1.textはviewに載っているLabelにIBOutletで接続したUILabelへの接続。独自に作ったXibに合わせて変更を。

また、Cellにコントローラを埋める場合はCellの使い回しをセルの種類単位で分けないとぐちゃぐちゃになるとの事。

セルの高さ指定

必ずFloat型の数値を返しておくこと。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%s",__func__);
    return 100.0;
}

セル選択時の表現の変更

セルを生成しなおしたりできる。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%s",__func__);
}

セルの選択解除時の変更

変更をデフォルトに戻しておく。

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"%s",__func__);
}

XibのIBOutletの設定

File’sOwnerのCustomClassの項目はMasterViewControllerにしておく。
※これは記述無しでも駆動する。記述が無い場合はデフォルトの値が入るので、Cell
Cell側のCustomClassの項目はCellにする。
Cells'Class

IBOutlet付きのメンバはCell下のLabel – Label1等に直接接続する。
IBOutlet

デフォルトのプロパティに準拠

UITableViewCellはデフォルトでUILabelを複数保持している。
これらのプロパティ名はtextLabelとdetailTextLabelなのでこれらの既存プロパティをメンバ変数と一緒に扱う事で上書きができる。無為にプロパティを増やさなくて済む。

サンプル

Cell.h

@interface Cell : UITableViewCell
{
    NSNumber* num_;
@private
    IBOutlet UILabel* label1_;
    IBOutlet UILabel* label2_;
    IBOutlet UIImageView* icon_;
    IBOutlet UILabel* detailTextLabel_;//既存プロパティ用に追加。
    IBOutlet UILabel* textLabel_;//既存プロパティ用に追加。
}

Cell.m

@synthesize detailTextLabel = detailTextLabel_;
@synthesize textLabel = textLabel_;

これで既存プロパティと共通化させる事が出来た。

下の画像のセル中央部分がオリジナルのプロパティ。右側がデフォルトのプロパティを利用した表示。
Screen Shot 0024-09-09 at 13.51.26

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です