Nibを活用しTableViewやCollectionViewでカスタムセルを使う方法を解説

そもそもセルクラスには以下の二種類があるよ。

  • UIKitに用意された既存のセルクラス
  • 自前で用意するカスタムセルクラス

前者と比較して後者のカスタムセルクラスは自前で用意する分多少工数がかかるが、自由にレイアウトを組めるかつ複数のViewController間で使い回したりが出来るため大きな仕様の変更にも強いよ。このような感じでカスタムセルを使うメリットは大きいので、基本的にはどのアプリでもカスタムセルを使うのが一般的だよ

カスタムセルを使用するための手順

そんなカスタムセルを使うための大まかな手順をリスト化するとこうなるよ。ちなみにTableViewもCollectionViewもどちらも同じ工程で実装が可能だよ。

  1. Nibファイルの作成
  2. Storyboardの実装
  3. ViewControllerの実装

それでは手順を解説していくよ

1. カスタムCell(Nib)の作成

まずカスタムCellとして使うNibファイルを作成するよ。ここで生成されたNibはパーツのように複数のViewController間で使い回しが可能である点が大きな特徴で、この挙動により高速なパフォーマンスを実現できるよ。(詳しくはNibについての公式ドキュメントを参照)

CustomTableViewCell.xibCustomTableViewCell.swiftを作成する

「New」→「File」→「Cocoa Touch Class」を選択。今回はCustomTableViewCellというクラスを生成するよ

上画像の通り、以下の二点を忘れないようにしよう。

  • 「Also create XIB file」にチェックマーク
  • 「Subclass of」にはUITableViewCell

ちなみに拡張子である.xibについてだが、ここは深く考えずにnib=xibと考えてもらえると良いよ

・ xib上に任意のUIパーツの設置しoutlet接続しておく

正しくできていればCustomTableViewCell.xibCustomTableViewCell.swiftが生成されているはずだよ。そしてお互いのファイルが対応しているものとして既に関連付けされていはずだよ。コードで加工しておきたい部品はoutlet接続しておこう。ここではUILabelを設置し、mainLabelというプロパティとしてoutlet接続を行っているよ

2 Storyboardの実装

通常の実装で行うTableViewのoutlet接続に加え、以下の二つの工程を行う必要があるよ。尚、TableViewのoutlet接続の仕方についてはUIViewControllerでTableViewを実装する方法に記載されているからここでは割愛するよ。

  • TableViewにCellを追加する
  • Cellの関連付けとReuseIdentifierの定義

順次解説するよ

・TableViewにCellを追加する


delegateとdatasourceの設定も忘れずに行おう。(詳しくはUIViewControllerでTableViewを実装する方法を参照)

・Cellの関連付けとReuseIdentifierの定義

下画像のように追加したセルの関連付けを行うよ

次に下画像のようにReuseIdentifierの定義を行うよ。ReuseIdentiferとははTableViewまたはCollectionView内で描画するセルを識別するための名前のようなものでクラス名とはまた別のものだよ。

3. ViewControllerの実装

Storyboardの実装が終了したらあとはViewControllerにコードを書いていくよ。主に行うことは次の二つだよ

  • registerによるカスタムCellの登録
  • 各delegateメソッドの実装

順次解説していくよ

・UITableViewのメソッド、registerによるカスタムCellの登録

カスタムセルの描画を行うためにはまず、viewDidLoad()内で使用するカスタムセルの登録をしておく必要があるよ。登録にはTableView(CollectionView)のメソッド、registerを呼び出すよ

func register(_ cellClass: AnyClass?, forCellReuseIdentifier identifier: String)  

公式ドキュメントを見ると登録したいCellクラスを渡す引数「cellClass」とIdentifierを渡す引数「forCellReuseIdentifier」があり、今回「cellClass」にはNibを渡すことになるよ。

override func viewDidLoad() {  
    super.viewDidLoad()  
    // Do any additional setup after loading the view.  
    let nib = UINib(nibName: "CustomTableViewCell" bundle: nil)  //register()の引数に渡す定数「nib」を定義  
    tableView.register(nib, forCellReuseIdentifier: "CustomTableViewCell")  //ココ  
}  
参考

公式ドキュメントを見ると、Nibをコードで定義するには以下のような形になる

UINib(nibName: String, bundle: Bundle?)  

・各delegateメソッドの実装

続いて行数を定義するnumberOfRowsと描画するセルの定義・加工を行うcellForRowAtを実装しよう。下のコードではoutlet接続しておいたmainLabelの加工を行っているよ。カスタムセルを使用する場合のcellForRowAtの記述については※で詳しく説明しているよ。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {  
    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell   
    cell.mainLabel.text = "\(indexPath.row)行目"     
    return cell  
}  
dequeueReusableCellについて

公式ドキュメントによると一個一個のCellは再利用される形で描画されており、生成し終えたCellを再生成するためのラインから取り除くための処理を行うのがこのメソッドらしい。これによってメモリを使わずに大量のCellを描画できるようだよ。

This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered. If no cell is available for reuse and you did not register a class or nib file, this method returns nil.
(このメソッドは使用しているセルクラスや登録したNibファイルが使用可能あるいは生成可能な場合、既に生成されたセルをキューから外します)

func dequeueReusableCell(withIdentifier identifier: String) -> UITableViewCell?  
※「as」によるキャストについて

定義する際にasでセルクラスにキャストしておかないと、ViewController側からxib上で設置・outlet接続を行ったプロパティ(上記の例で言うとcell.mainLabel)にアクセスできない。

まとめ

  • カスタムセルを定義する際には「Nibファイル」を用いる。これは使い回しが可能なセルである。
  • カスタムセルを描画するためには以下2つのメソッドが必要。両者ともReuseIdentifierの値を引数に取るので、Storyboardから忘れずに設定しておこう
    • セルを登録するregister(viewDidLoad()内に記述)
    • カスタムセルクラスを定義するdequeueReusableCell(TableViewの場合はcellForRowAt・CollectionViewの場合はcellForItemAtに記述)

最後までご覧いただきありがとうございました

こっちは真面目に作ってます。笑

サクっとプログラミング

iOSアプリ開発のあれこれがまとまるwebサイト