2013年7月16日火曜日

UITableViewについて - UITableViewのセルをカスタムセルを使ったほうがいい(3)

前回前々回に引き続きカスタムセルについてです。

今回は前回書いた、カスタムセル生成時に初期化と表示するデータの設定を一つのクラスで行う方法について。

環境

  • Xcode : 4.6.2
  • iOS SDK : 6.1
  • デバッグ 実機 : iPod touch、バージョン6.1.3

目的

初期化と表示するデータの設定を一つのクラスで行う。
セルのコンテンツの重なりはないかと、セルの再利用が行われているかどうかを調べます。

作ってみる

それでは作っていきます。

今回は、

  • カスタムセルとしてUITableViewCellクラスを継承した「CustomCell」クラスを作成。
  • 初期化と表示するデータの設定をCustomCellクラス側で行う。new!!
  • Xibファイルは使わない。

また、初期化と表示するデータの設定をCustomCellクラス側で行うため、自作の初期化メソッド initWithCustomStyle:reuseIdentifier:labelData:メソッド を作成します。

プロジェクトの作成

プロジェクトは「Single View Application」で作成。

使用するクラス

  • ViewController.h/m - UIViewControllerクラス継承
  • CustomCell.h/m - UITableViewCellクラス継承

ViewController

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

ViewController.h

#import "ViewController.h"
#import "CustomCell.h"

@interface ViewController () 
@property(nonatomic, retain)UITableView *tableView;  // テーブルビュー
@property(nonatomic, retain)NSArray *datas;  // 表示するデータを入れる配列
@end

@implementation ViewController

@synthesize tableView=_tableView;
@synthesize datas=_datas;

-(id)init
{
    if (self=[super init]) {
        // セルに表示するデータの初期化
        self.datas = [NSArray arrayWithObjects:@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", nil];
    }
    
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // iOS 6.0以降からのセル再利用の設定
    // http://dev.classmethod.jp/smartphone/iphone/ios6-uitableview/
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CustomCell"];

    // テーブルビュー作成
    [self createTableView];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark -
#pragma mark - Private Method

// テーブルビュー作成
- (void)createTableView
{
    self.tableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain] autorelease];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    [self.view addSubview:self.tableView];
}

#pragma mark -
#pragma mark - Table view delegate

// セルのセクション数を設定
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

// セルの個数を設定
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.datas count];
}

// セル高さを設定
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100;
}

// セルの内容を設定
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"CustomCell";
    
    CustomCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (cell == nil)
    {
        // initWithCustomStyle:reuseIdentifier:labelData:メソッドで初期化と表示するデータの設定を行う
        cell = [[[CustomCell alloc] initWithCustomStyle:UITableViewCellStyleDefault
                                                             reuseIdentifier:CellIdentifier
                                                                     labelData:[self.datas objectAtIndex:indexPath.row]] autorelease];
        NSLog(@"CustomCell init");
    }
    
    return cell;
}

@end

CustomCell

CustomCell.h

#import <UIKit/UIKit.h>

@interface CustomCell : UITableViewCell
// 自作初期化メソッド
- (id)initWithCustomStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier labelData:(NSString*)labeldata;
@end

CustomCell.m

#import "CustomCell.h"

@implementation CustomCell

@synthesize label=_label;

// 自作初期化メソッド
-(id)initWithCustomStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier labelData:(NSString *)labeldata
{
    self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.label = [[UILabel alloc]initWithFrame:CGRectMake(120, 30, 150, 50)];
        self.label.text = labeldata;
        [self.contentView addSubview:self.label];
    }
    
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
}

-(void)dealloc
{
    [_label release];
    
    [super dealloc];
}

@end

結果

CustomCellクラス側で初期化と表示するデータの設定を行えた。
セルのコンテンツの重なりあり。
セルの再利用行われている。



おわり

セルのコンテンツの重なりが気になります。

ログを見ると"CustomCell init"が7回呼ばれているのですが、これは前回と変わりありません。

そもそもカスタムセル側ではデータを入れてはいけないのかな。

このエラーが消えるかどうか分かりませんが、次回はXibファイルを使ってやってみます。

0 件のコメント:

コメントを投稿