Table View Cell をカスタマイズする方法 (Swift)
前回は 「 Table View の使い方 」 で、iOS アプリの開発によく使われる Table View の基本的な使い方についてご説明しました。
その時は既定のスタイルを使いましたが、今回は UITableViewCell をカスタマイズする方法をご紹介します。
Table View Cell をカスタマイズすると、セルの好きな場所に好きなオブジェクトを置くことができます。
既定のスタイルでは画像はセルの左側にしか表示できないので、画像を右側に置いて、次のような Table View Cell を作ってみましょう。
Table View を使う準備をする
まずは Table View と Table View Cell を使う準備をします。
手順は 「 Table View の使い方 」 と全く同じですので、やった方はそのプロジェクトを開いて、そのまま次に進んでください。
「 Table View の使い方 」 をやっていない方は、Table View の使い方 の 3-1 から 3-4 をやって、Table View と Table View Cell を使う準備をしておいてください。
表示する動物データを準備する
前回はデータを保存するのに文字列の配列を使いましたが、今回は Animal という構造体を定義して、動物のデータを保存しておき、それを Table View に表示します。
構造体 (struct) というのは、いろんなデータ型の値をまとめて格納できるカスタムのデータ型です。
今回はひとつのセルに表示したい動物の情報は、動物の日本語名、英語名、画像の三つです。
ですので、NameJP(日本語名)、NameEN(英語名)、ImageName(画像名) の 3 つの文字列を格納できる Animal という名前の構造体を作ります。
Animal 構造体を作る
メニューバーの File > New > File... で iOS の Swift File を選択し Next をクリックして、Animal.swift ファイルを生成します。
そして、Animal.swift ファイルを開いて、その中に以下のコードを追加します。
struct Animal {
private(set) public var nameJP : String
private(set) public var nameEN : String
private(set) public var imageName : String
init(nameJP: String, nameEN: String, imageName: String) {
self.nameJP = nameJP
self.nameEN = nameEN
self.imageName = imageName
}
}
Animal 構造体に、nameJP、nameEN、imageName の 3 つの文字列のプロパティを定義しています。
private(set) public として定義しているのは、値を読むのはどこからでも読めますが、値をセットするのはイニシャライザー init を使ってしかできないようにする為です。
動物の画像を Assets.xcassets に追加する
次に、使用する動物の画像を Assets に追加しておきます。
左側のプロジェクトナビゲーターで Assets.xcassets を選択します。
そして、開いた画面の左側に、以下の画像をドラッグ&ドロップしておきます。
Animals の Array データを作っておく
続けて、データを表示するための Animal 構造体の配列データを作っておきます。
ViewController.swift ファイルを開いて、以下のコードを追加してください。
まずは、上のほうで animals という名前の Animal 型の配列を定義します。
var animals: [Animal] = []
loadData() というメソッドで、それぞれの動物の Animal オブジェクトを作って、animals に追加しています。
func loadData() {
animals.append(Animal(nameJP: "ふくろう", nameEN: "Owl", imageName: "owl"))
animals.append(Animal(nameJP: "とり", nameEN: "Bird", imageName: "bird"))
animals.append(Animal(nameJP: "らいおん", nameEN: "Lion", imageName: "lion"))
animals.append(Animal(nameJP: "かば", nameEN: "Hippo", imageName: "hippo"))
animals.append(Animal(nameJP: "くま", nameEN: "Bear", imageName: "bear"))
animals.append(Animal(nameJP: "はりねずみ", nameEN: "Hedgehog", imageName: "hedgehog"))
animals.append(Animal(nameJP: "ぞう", nameEN: "Elephant", imageName: "elephant"))
}
そして、viewDidLoad() の下のほうで、先ほどの loadData() を呼び出しデータを生成するようにしておきます。
loadData()
前回使った systemIcons 配列は使わないので、宣言と使われている箇所を削除しておきます。どれを消すかわかりやすいように、ここではコメントアウトしています。
tableView(_:numberOfRowsInSection:) では、systemIcons.count の変わりに animals.count を返すようにしておきます。
return animals.count
Table View Cell をカスタマイズする
ここからが本題の Table View Cell をカスタマイズする方法です。
AnimalTableViewCell クラスを作る
まずは、カスタムの UITableViewCell のクラスをつくります。
メニューバーの File > New > File... で iOS の Cocoa Touch Class を選択し Next をクリックして、Class に AnimalTableViewCell、Subclass of に UITableViewCell を選択しファイルを生成します。
Table View Cell のクラスを設定する
次に、Table View Cell のクラスを AnimalTableViewCell を設定します。
左側のプロジェクトナビゲーターで Main.storyboard を選択します。
Table View Cell を選択した状態で、右側のユーティリティエリアの Identity インスペクターを選択します。
上のほうにある Custom Class のクラスの Class のドロップダウンリストから AnimalTableViewCell を選んでおきます。
Table View Cell にオブジェクトを配置する
Table View Cell に Label や ImageView などのオブジェクトを配置していきます。
まずは、Table View と Table View Cell の 1 行の高さを 100 に設定します。
Table View を選択した状態で Size インスペクターを開きます。
一番上の Table View の Row Height に 100 を設定します。
そのまま、Table View Cell を選択し、Size インスペクターで Table View Cell の Row Height も 100 に設定します。
次に Table View Cell を選択したまま、Attribute インスペクターを開き、Style を Custom に変更し、Identifier を AnimalTableViewCell に変更しておきます。
それでは、Table View Cell に Label や Image View などのオブジェクトを配置していきましょう。
以下のように右側に Image View をひとつと、Label を 3 つ配置します。
右上の➕ボタンをクリックしてオブジェクトライブラリーを表示し、UIImageView を探して、Table View Cell の右側にドラッグ&ドロップしてください。
Image View をだいたい表示したい場所に配置したら、コンストレイントを追加します。
- Spacing to nearest neighbor - 右: 15
- Width: 100
- Height: 100
- Alignment: Vertically in Container
これはデザインを確認する為にですが、Attribute インスペクターを開き、owl を選択しておきます。
Content Mode は Aspect Fit のままで大丈夫です。
次は日本語名用の Label を 配置します。
オブジェクトライブラリーから Label を次のような感じで配置し、Attribute インスペクターで次のように設定します。
- Text: ふくろう
- Color: Dark Gray Color
- Font: Helvetica Bold 36.0
そして、次のようにコンストレイントを追加しておきます。
- Spacing to nearest neighbor - 上: 5
- Spacing to nearest neighbor - 左: 8
- Width: 260
- Height: 50
続いて「英語:」用の Label を以下のように配置します。
- Text: 英語:
- Color: Light Gray Color
そして、次のようにコンストレイントを追加しておきます。
- Spacing to nearest neighbor - 上: 1
- Spacing to nearest neighbor - 左: 8
- Width: 52
- Height: 20
最後に英語名用の Label を以下のように配置します。
- Text: Owl
- Color: Light Gray Color
そして、次のようにコンストレイントを追加しておきます。
- Spacing to nearest neighbor - 上: 1
- Spacing to nearest neighbor - 左: 1
- Width: 215
- Height: 20
一応、今回私が指定した値を書きましたが、ラベルや画像の大きさや位置など、お好みで配置していただいて大丈夫です。
Table View Cell のアウトレットを生成する
次に Table View Cell のアウトレットを生成します。
ストーリーボードで、AnimalTableViewCell の中のふくろうの Image View など選択した状態で、メニューから Editor > Assistant Editor を選択するか、Adjust Editor Options ボタンの Assistant から Assistant Editor を開きます。
Assistant Editor が開いたら、開かれたファイルが AnimalTableViewCell.swift であることを確認してください。
違う場合は、Assistant Editor の上の Automatic をクリックして、AnimalTableViewCell.swift に変更してください。
そして、日本語名、英語名のラベルと、画像のImage View から、以下のように 3 つのアウトレットを生成しておいてください。
@IBOutlet weak var animalNameJPLabel: UILabel!
@IBOutlet weak var animalNameENLabel: UILabel!
@IBOutlet weak var animalImageView: UIImageView!
これで、カスタムの Table View Cell を使う下準備は完了です。
Table View にデータを表示する
それでは、カスタムの Table View Cell にデータを表示してみましょう。
tableView(_:cellForRowAt:) インスタンスメソッドに次のようにコードを追加してください。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = myTableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath)
guard let cell = myTableView.dequeueReusableCell(withIdentifier: "AnimalTableViewCell", for: indexPath) as? AnimalTableViewCell else {
fatalError("Dequeue failed: AnimalTableViewCell.")
}
cell.animalNameJPLabel.text = animals[indexPath.row].nameJP
cell.animalNameENLabel.text = animals[indexPath.row].nameEN
cell.animalImageView.image = UIImage(named: animals[indexPath.row].imageName)
return cell
}
今回は dequeueReusableCell で得られた UITableViewCell を guard let で AnimalTableViewCell 型にキャストし、失敗した時は fatalError で実行を終了するようにしています。
そして、animals 配列の indexPath.row 番目の Animal オブジェクトの nameJP、nameEN を cell の animalNameJPLabel.text と animalNameENLabel.text に設定しています。
続けて、imageName から UIImage を生成して、cell の animalImageView.image に設定しています。
これでカスタム Table View Cell にデータを表示する為のコードを書き終わりました。
念のため ViewController.swift の全体のコードを載せておきます。
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var animals: [Animal] = []
@IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
myTableView.dataSource = self
myTableView.delegate = self
loadData()
}
func loadData() {
animals.append(Animal(nameJP: "ふくろう", nameEN: "Owl", imageName: "owl"))
animals.append(Animal(nameJP: "とり", nameEN: "Bird", imageName: "bird"))
animals.append(Animal(nameJP: "らいおん", nameEN: "Lion", imageName: "lion"))
animals.append(Animal(nameJP: "かば", nameEN: "Hippo", imageName: "hippo"))
animals.append(Animal(nameJP: "くま", nameEN: "Bear", imageName: "bear"))
animals.append(Animal(nameJP: "はりねずみ", nameEN: "Hedgehog", imageName: "hedgehog"))
animals.append(Animal(nameJP: "ぞう", nameEN: "Elephant", imageName: "elephant"))
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return animals.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = myTableView.dequeueReusableCell(withIdentifier: "AnimalTableViewCell", for: indexPath) as? AnimalTableViewCell else {
fatalError("Dequeue failed: AnimalTableViewCell.")
}
cell.animalNameJPLabel.text = animals[indexPath.row].nameJP
cell.animalNameENLabel.text = animals[indexPath.row].nameEN
cell.animalImageView.image = UIImage(named: animals[indexPath.row].imageName)
return cell
}
}
ビルドしてシミュレーターで実行する
それでは、ビルドして実行してみましょう。
ツールバー左側の ボタンをクリックすると、選択されているシミュレータが立ち上がり、アプリがインストールされて実行されます。
animals 配列に入っている動物の情報が、カスタマイズした Table View Cell 通りに Table View に表示されましたね。
以上、Table View Cell をカスタマイズする方法についてご説明しました。