SwiftのTableViewCellを使ってTableViewを自由にカスタマイズ

# 概要

　この記事は初心者の自分がRESTful なAPIとswiftでiPhone向けのクーポン配信サービスを開発した手順を順番に記事にしています。技術要素を1つずつ調べながら実装したため、とても遠回りな実装となっています。

前回の [swiftで配列型のJSONから値を取り出す](https://qiita.com/Ajyarimochi/items/50cdc57f898b79cfb48e) でクーポンの詳細情報や利用可能店舗名、有効期間の情報を取得できるようになりましたので、それらをアプリ画面に表示するようにTableViewを改造します。

### 参考

* やさしくはじめる　iPhoneアプリ作りの教科書　森 巧尚 著　マイナビ

### 環境

Mac OS 10.15
Swift5
Xcode11.1

# 手順

* Main.storyboardでTableViewCellをデザイン
* 配置したラベルにそれぞれの情報を表示できるようにViewControllerを改造
* 動作確認


### Main.storyboardでTableViewCellをデザイン

　現在は subtitle というTableViewの標準のデザインを使い、メイン情報を詳細情報の2つを表示する仕様になっています。3つ以上の情報をtableViewに表示したい場合は標準デザインが対応していないためオリジナル仕様のTableViewCellを作る必要があります。

　まず既に配置済みのTableViewの上にTableViewCellを配置します。ObjectsのウィンドウはXcodeの右上の「＋」ボタンで表示できます。
<img width="519" alt="put-tableview-tableviewcell.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526594/5bcbdf0b-7ee1-48e1-adbd-8b8a8f1d58ee.png">


配置したTableViewCellのIdentifier にTableViewCellを特定するための名前をつけます。
<img width="260" alt="set-identifier.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526594/2242bb5d-4792-036b-f11a-0104793b1dfa.png">



右側の「show the size inspector」でTableViewCellの高さを200ptに設定し、TableViewCellの上に、クーポンの情報を表示するためのLabelを配置しました。ラベルの用途は下記の通りです。

* クーポン特典を表示するラベル
* クーポンのコメントを表示するラベル
* 利用可能店舗を表示するラベル
* 開始利用開始日と利用期限を繋げて利用可能期間を表示するラベル


それぞれのラベルをプログラムから識別するためにtag（通し番号）をつけます。
<img width="616" alt="set-tag-to-labels-mark.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526594/dec44b8b-306b-ead2-14b5-126778fd971d.png">

タグ番号の振り分けは下記の通りにしました。

1. クーポン特典を表示するラベル
2. クーポンのコメントを表示するラベル
3. 利用可能店舗を表示するラベル
4. 開始利用開始日と利用期限を繋げて利用可能期間を表示するラベル


クーポン特典とコメントは複数行で表示させたいので行数を2行に設定します。LabelのLinesで行数を設定できます。
<img width="259" alt="set-label-lines-2-mask.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526594/633091b2-31b1-c0b1-5247-6952554ea07b.png">



以上でTableViewCellのデザインは完了です。


### 配置したラベルにそれぞれの情報を表示できるようにViewControllerを改造。

「10_swiftでクーポンを表示する画面を実装する」で作成したプログラムを改造していきます。
改造する箇所は関数`func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)`だけです。


まず、セルオブジェクトを作るコードをMain.storyboard でデザインしたCell（couponCell）のセルオブジェクトを作る形式に変えます。

**変更前**

```swift

let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "couponCell")
```

**変更後**

`withIdentifier:` のところは 作成したTableViewCellのIdentifierに設定した名前（今回は couponCell）を指定します。

```swift

let cell = tableView.dequeueReusableCell(withIdentifier: "couponCell", for: indexPath as IndexPath)
```


次に、セルの高さを設定します。（Main.storyboardでも設定しましたが、ViewControllerでも設定しないと反映しませんでした。）

```swift

tableView.rowHeight = 200
```


次に各Labelに表示する値を設定します。
ラベルオブジェクトを作るところで、`cell.viewWithTag( )` の「( )」に設定したtagの通し番号を入力します。ラベルに表示する文字列を設定する部分で、変数`coupon`は`[String: Any]`型なので、`String`型にキャストします。コードは以下のようになります。

```swift

//ラベルオブジェクトを作る
let labelBenefit = cell.viewWithTag(1) as! UILabel
//ラベルに表示する文字列を設定
labelBenefit.text = (coupon["coupon_benefits"] as! String)
```

これを4つのラベル分、実装します。



出来上がったコードはこちらです。

```swift

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let coupon = self.coupons[indexPath.row]
        //セルを作る
        let cell = tableView.dequeueReusableCell(withIdentifier: "couponCell", for: indexPath as IndexPath)
        
        tableView.rowHeight = 200
        
         //各ラベルに値を設定する
        let labelBenefit = cell.viewWithTag(1) as! UILabel
        labelBenefit.text = (coupon["coupon_benefits"] as! String)

        let labelExplanation = cell.viewWithTag(2) as! UILabel
        labelExplanation.text = (coupon["coupon_explanation"] as! String)

        let labelStore = cell.viewWithTag(3) as! UILabel
        labelStore.text = (coupon["coupon_store"] as! String)

        let labelDay = cell.viewWithTag(4) as! UILabel
        labelDay.text = "有効期間： " + (coupon["coupon_start"] as! String) + " ～ " + (coupon["coupon_deadline"] as! String)
```


### 動作確認
実行したところ、デザインした通りにクーポンが表示されています。
<img width="385" alt="app-test-14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526594/16ff6ebc-e3f6-0dd4-0475-2f5885b02059.png">

これで少しクーポンらしくなりました。

次回は、webAPI側をRESTfulなAPIに改造します。