【Swift】tableViewとtableViewCellの使い方とソースコード事例

SwiftのUITableViewはテーブルを表示するクラスです。ちなみにUIScrollViewクラスを継承しています。

今日はソースコード上でのUITableViewとその中のセルを扱うUITableViewCellクラスの使い方を整理しています。

UITableViewの宣言の仕方とインスタンス生成

まず宣言は以下のように記述。

リファレンスを見ると以下のようにinitメソッドが用意されている。

引数のframeはCGRectオブジェクトで指定、
UITableViewStyleは
・UITableViewStyle.plain
・UITableViewStyle.grouped
の2つがあるのでどちらか設定する。

初期化は例えば以下のようにやる。

スタイルの見た目の違いは以下のような感じ。


UITableViewクラスのプロパティはたくさんある。。たくさんありすぎるので全部書かない。詳細はリファレンス参照。

rowHeight: CGFloat
sectionHeaderHeight: CGFloat
sectionFooterHeight: CGFloat
estimatedRowHeight: CGFloat
stimatedSectionHeaderHeight: CGFloat

◆TableViewの境界線を指定できる

UITableViewのseparatorStyleプロパティには、UITableViewCellSeparatorStyle.none または UITableViewCellSeparatorStyle.singleLine(デフォルト)を入れる。separatorColorにはUIColorの色を指定できる。

TableViewとTableViewCellの使い方

ここからが重要なポイント。TableViewクラスを使うには一連の流れがあり、そのとおり実装していくことになる。

①ViewControlerにデリゲートメソッドを2個記述

これでTalbeViewに関連するイベントを取得したり、値の設定ができるようになる。

②TableViewのインスタンスを生成して

③デリゲートを設定

④テーブルや中に配置するセルを定義する各種メソッドを定義

以下のメソッドがUITableViewDelegate, UITableViewDataSourceクラスにあるのでオーバーライドで上書きして再定義する。

  1. テーブル内のセクション数を決めるメソッド

    func numberOfSections(in tableView: UITableView) -> Int {}

  2. セクション内のセル数を決めるメソッド・・・★必須

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {}

  3. セルのインスタンスを生成するメソッド・・・★必須

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}

  4. セルの高さを決めるメソッド

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {}

  5. セクションのタイトルを設定するメソッド

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {}

  6. セクションの高さを設定するメソッド

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {}

この中で必須なのは★必須をつけている。他のメソッドは記述しなければデフォルト値が使われる。

詳しく見ていく。

1.テーブル内のセクション数を決めるメソッド

このようにInt型で数字を返してあげると、それがセクション数になる。TableViewにおいて「セクション」と「セル」は重要なので覚えておきたい。セクションとセルは以下のようになっている。

2.セクション内のセル数を決めるメソッド・・・★必須

このようにInt型で数字を返してあげると、それがセル数になる。セクションの中に何個のセル(行)を入れるかを設定できる。例えばメニューを3つ作りたいと思えば

などとして、return menus.countとやるようなイメージ。そうするとメニューの数だけセル(行数)を確保できる。

第2引数のsectionには現在のセクション番号が来る。numberOfRowsInSectionは引数のラベル。たぶんシステム内部の呼び出し側で使われている。このメソッド内では引数はsectionという変数名で使えば良い。

sectionは0から始まる(0,1,2…という)番号が振られている。

セクション0はセルが3つ、セクション1はセルが4つなど指定する場合はif文かswitchでセル数を返すことになるかもしれない。

3.セルのインスタンスを生成するメソッド・・・★必須

ここが重要です。このメソッドの中でセルを生成していきまいす。

ここで一旦セル(UITableViewCell)を調べていきます。

リファレンスを見ると初期化メソッドは以下のようになっている。

public init(style: UITableViewCellStyle, reuseIdentifier: String?)

第1引数のstyleではセルのスタイルを指定できる。以下の4つから選択して指定すること。
UITableViewCellStyle.default
UITableViewCellStyle.subtitle
UITableViewCellStyle.value1
UITableViewCellStyle.value2

セルの見た目は以下のように変わる。

第2引数のreuseIdentifierは再利用識別子と訳すことができる。何を指定するかわからないがString型なので適当な文字列を入れておけば良いと思う。

初期化は次のようにやる。

UITableViewCellには以下のプロパティがある。

それぞれに値をセットして使うことになる。

のようにして設定する。上の画像のようにtextLabel、detailTextLabel、imageViewが表示される。

これでセルを生成できるようになった。

なのでこのメソッドは

以下のように使えばよく、TableViewにTableViewCell(1行)を追加できる。

第2引数のcellForRowAtは第2引数のラベルなのでここでは(開発者は)使わない。このメソッド内ではindexPath変数を使う。
indexPathには以下の値が入っている。

indexPath.section → 現在のセクション番号(0、1、2‥)
indexPath.row → 現在の行番号(0、1、2‥)

この変数を使って、セクション○番の○行目のcellに何を記述するかを決める感じになる。

4.セルの高さを決めるメソッド

CGFloat型でセルの高さを返せば設定される。

このメソッドを使うとindexPathには前述の現在のセクション番号と行番号が入ってくるので、1個1個のセルに対して高さを設定できる。

tableView.rowHeightでもセルの高さを指定できるが、rowHeightは全部のセルの高さを一律に決めるので使い分けできる。

5.セクションのタイトルを設定するメソッド

こうすると1番目のセクションだったら、「第1セクション」というタイトルが設定される。

6.セクションの高さを設定するメソッド

これもCGFloat型でセクションの高さを設定できる。

必要に応じてこれらのメソッドをオーバーライドして定義すれば、TableViewを構成することができる。

◆ソース全文

TableViewのその他のメソッド

セルを選択したときのイベントを処理する

以下のメソッドもUITableViewDelateに用意されているのでオーバーライドして定義すれば、セルが選択された時にこのメソッドが動くようになる。

TableViewをリロードするメソッド

とすればTableViewをリロードできる。テーブル内のどこかを編集した場合の後などにこのメソッドをよんでテーブルの再描画をしてもらう。

この他にメソッドがいくつかある。

例えば
tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
他にもいっぱいあるので割愛。

一律でテーブルのセルの高さを自動調整にする方法

セル内のUILabelの文字数が多かったりした場合に備えて、セルの高さも自動的に調整してくれる方が良い場合がある。

そのために以下のプロパティを設定する。

tableView.estimatedRowHeight
tableView.rowHeight

1行目は推定のセル高さをあらかじめ指定しておくことでTableViewのロード時間が早くなるのでこれをやると良いとされている。テーブルの高さが可変の場合は高さを計算するのに時間がかかるので、ここで推定高さを指定すると良い。

次に2行目は指定されたディメンションのデフォルト値を使用(意味はわからない)が、こうするとテーブルのセルの高さが自動的に調節される。

そしてセルの中のUILabelについても行数を可変にする処理を入れる。

セルを生成するときに中に表示する詳細のラベルの行数を無制限(0)にしておいて、textプロパティに文字列を代入します。

以下のようになる。(クリック拡大)

tableViewメソッドが呼ばれるタイミングを理解

気になるのはこれらのtableViewメソッドがいつ呼ばれているか。print文でそれぞれのメソッドに出力をしておけば理解ができる。
どのタイミングで呼ばれるかを知ることがUITableViewを理解する助けになる。

self.view.addSubview(myTableView1)

myTableView1.reloadData()
が実行された後。

numberOfSectionsメソッドが呼ばれてセクション数を指定して

tableView(_ tableView: UITableView, numberOfRowsInSection section: Int)が呼ばれてセル数を指定して

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCellが呼ばれて
すべての行数(すべてのindexPath.sectionのindexPath.rowの数)だけ呼ばれる。
行数が3個あれば3回よばれる。indexPath.rowをprintすれば0, 1, 2と表示されるので。

こんな感じで自動的に呼ばれていってるのが実験でわかった。