Help us understand the problem. What is going on with this article?

Storyboard上のUITableViewCellをxibで作る場合はregisterNib:forCellReuseIdentifier:メソッドが便利

More than 3 years have passed since last update.

Storyboardを使ってUITableViewのある画面を作り、そのCellを複数画面で使いまわすためにxibとして作成するときのTipsです。

UITableViewにiOS5から追加されたregisterNib:forCellReuseIdentifier:メソッドを使うことで、作成したxibをUITableViewに登録することができ、nilチェックとloadNibを必要としないシンプルなコードにすることができます。

コードで例を示すために使いまわしたいCellを"SampleTableViewCell"とします。作成するのは3つ

  • SampleTableViewCell.xib
  • SampleTableViewCell.h
  • SampleTableViewCell.m

ここで説明するregisterNib:forCellReuseIdentifier:メソッドは、UITableViewを保持するUITableViewControllerのviewDidLoadなどで呼び出します。これによってCell用に作成したxibファイルがUITableViewに登録されます。

- (void)viewDidLoad
{
    [super viewDidLoad];

    UINib *nib = [UINib nibWithNibName:@"SampleTableViewCell" bundle:nil];
    [self.tableView registerNib:nib forCellReuseIdentifier:@"Cell"];
}

あとはStoryboardでStaticやDynamicなCellを呼び出す時と同じように次のようにします。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    SampleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...

    return cell;
}

これで下記のようにcellの再利用をnilチェックし生成する必要はありません。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    SampleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        // こういう処理は必要なくなるよと
        cell = [SampleTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
          reuseIdentifier:CellIdentifier];
    }
    // Configure the cell...

    return cell;
}

なぜ再利用のチェックと生成を行う必要がないかというと、先ほどの説明通りにnibを登録してればnilを返すことがないからです。これについてはAppleのUITableViewのリファレンスでdequeueReusableCellWithIdentifier:がnilを返す場合について下記のように言及されていましたので参考になります

  • 再利用されるcellが存在しない時
  • nibが登録されていない時(iOS5から)
  • Classが登録されていない時(iOS5から)

つまり、nilが返るという状態は実装ミスです。実装ミスがすぐに発覚するので良いつくりといえるでしょう。

したがって、先述のメソッドによりCellが登録されることで内部キューになければ自動で生成を行なってくれるため、Cellの再利用チェックと生成のコードが必要ないわけです。余談ですがStoryboardのCellを使うようになってから再利用チェックを書く必要がなくなっていたのはStoryboardが登録の手続きを行なっていたからなんですね。

これらは当然、Storyboard+xibの時にかぎらず、UITableViewでさえあれば使えます。また、registerClass:forCellReuseIdentifier:によりクラスを指定できるためxibである必要も有りません。

yimajo
株式会社キュリオシティソフトウェアの代表です。iOSアプリを作っています。最近はRxSwift研究読本書いてます。 https://swift.booth.pm/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした