[追記]大事な手順を書き忘れていました。セルの再利用のための手順を最後に追記しています。
間違ってるかもしれないけど、たぶんこう。
View Templateを選択して、新しいXIBファイルを作成します。
名前を付けて保存します。ここではFeedListCell.xibとします。
Xcodeで対応するUITableViewCellを継承したクラスと、View Controller (FeedListCellController) を作ります。
View ControllerはUIViewControllerを継承します(UITableViewControllerではない)。
また、セルをインスタンス変数として保持します。ここではFeedListCellのインスタンスです。
#import <UIKit/UIKit.h> @interface FeedListCell : UITableViewCell { IBOutlet UILabel *titleLabel; IBOutlet UILabel *unreadCountLabel; IBOutlet UILabel *readCountLabel; IBOutlet UIImageView *unreadMark; } @property (nonatomic, retain) UILabel *titleLabel; @property (nonatomic, retain) UILabel *unreadCountLabel; @property (nonatomic, retain) UILabel *readCountLabel; @property (nonatomic, retain) UIImageView *unreadMark; @end
#import "FeedListCell.h" @implementation FeedListCell @synthesize titleLabel; @synthesize unreadCountLabel; @synthesize readCountLabel; @synthesize unreadMark; - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; } - (void)dealloc { [unreadMark release]; [readCountLabel release]; [unreadCountLabel release]; [titleLabel release]; [super dealloc]; } @end
#import <UIKit/UIKit.h> #import "FeedListCell.h" @interface FeedListCellController : UIViewController { IBOutlet FeedListCell *cell; } @property (nonatomic, retain) FeedListCell *cell; @end
Interface Builderに戻って、FeedListCell.xibのFile's OwnerにFeedListCellController、UITableViewCellにFeedListCellを設定します。
View ControllerのセルのインスタンスとViewのインスタンスをセルに接続します。
FeedListCellControllerのcell変数と、view変数を両方ともFeedListCellに接続します。
FeedListCellのインスタンス変数にセルの部品を接続します。
これで、セルの準備は完了です。
実際にTable Viewで表示する場合は次のように記述します。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"FeedListCell"; FeedListCell *cell = (FeedListCell *)[tableView dequeueReusableCellWithIdentifier:identifier]; if (cell == nil) { FeedListCellController *controller = [[FeedListCellController alloc] initWithNibName:identifier bundle:nil]; cell = (FeedListCell *)controller.view; [controller release]; } [cell.titleLabel setText:[NSString decodeXMLCharactersIn:[feed objectForKey:@"title"]]]; [cell.unreadMark setImage:unreadMark2]; [cell.readCountLabel setText:[NSString stringWithFormat:@"%d", [unread_count intValue] - [listOfReadEachEntry count]]]; [cell.unreadCountLabel setText:[NSString stringWithFormat:@"%@", unread_count]]; return cell; }
注意
セルにテキストフィールドなど (UITextField, UITextView) を含める場合は、解放されるときにデリゲートを解放するのを忘れないようにします。
デリゲートが残ったままセルが解放されると、クラッシュします。
#import "DiaryCell.h" @implementation DiaryCell @synthesize diaryTextView; @synthesize submitButton; @synthesize draftButton; - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; } - (void)dealloc { [draftButton release]; [submitButton release]; [diaryTextView setDelegate:nil]; [diaryTextView release]; [super dealloc]; } @end
以下の部分です。
[diaryTextView setDelegate:nil];
[diaryTextView release];
[追記]セルのインスタンスを再利用するために必要な手順
UITableViewCellのインスタンスは、最初に一画面分のインスタンスを作ったら、後は同じインスタンスを再利用します。
そうしないと、スクロールするたびに新しいインスタンスが作られるので、メモリが足りなくなります。
以下はその再利用のためのコードです。セルのインスタンスに名前を付けて、保持します。
名前を指定して呼び出し、存在しなかった場合だけ(つまり最初の一回だけ)、新しくインスタンスを生成します。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"FeedListCell"; FeedListCell *cell = (FeedListCell *)[tableView dequeueReusableCellWithIdentifier:identifier]; if (cell == nil) { FeedListCellController *controller = [[FeedListCellController alloc] initWithNibName:identifier bundle:nil]; cell = (FeedListCell *)controller.view; [controller release]; }
そういう仕組みなので、Interface Builderで作成したセルは再利用するために名前をつける必要があります。
セルのファイル (FeedListCell.xib) を開き、UITableViewCellを選択して、「Attributes Inspector(コマンド+1)」を開きます。
TableViewCell>Identifierに任意の名前を設定します。
もちろん、ここで設定した値をコードから使用します。