[Swift 5] TableViewCell間に余白(スペース)を入れる方法の一案

TableViewのCellとCellの間にスペースを設けたかっただけなのですが、意外と面倒で注意点も多かったので書き残しておきます。

結局この方法は採用せず、CellのcontentView内部のViewのサイズを小さくして実現したのですが、一つの方法として書き残しておきます。

今回書くのは、SectionのHeaderで表現する方法です。

## Storyboardで下準備

### TableViewを配置します。

左右の余白は好みだと思いますが、上下はSafeareaにぴったりくっつけると望ましい挙動になるかと思います。

### Viewに好みの背景色(Background)を設定し、TableViewの背景色は透明に設定しましょう。

TableViewの色を透明にしないと、セルが存在するところ以外が設定色で塗りつぶされてしまいます。

### TableViewのStyleはGroupedにする

Plainのままだと、ヘッダーがスクロールに追従してくるため期待通りの挙動になりません。

StoryboardでTableViewのStyleをGroupedに設定しましょう。

## 余白をSectionのHeaderで表現する

残念ながら、Cell間の余白設定は用意されていないようなので、SectionのHeaderを使って表現します。

1Sectionにつき1Rowのみを表示します。

```ViewController.swift
func numberOfSections(in tableView: UITableView) -> Int {
    return contents.count  // 表示するデータが入っている配列を想定
}
```

Row(行)は常に1つのみになります。

```ViewController.swift
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1  // 要素数はsectionで表現するため、rowは常に1個のみ
}
```

いつも通りセルの中身を設定します。

```ViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Ptorotype Cell
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    // セルの設定を行う...
    
    return cell
}
```

ヘッダーの高さを設定

```ViewController.swift
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 8  // お好みで
}
```

ヘッダーの色を透明にする

```ViewController.swift
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let marginView = UIView()
    marginView.backgroundColor = .clear
    return marginView
}
```

フッターは不要なので表示しないようにする。

この時、単に `return 0`を指定しても非表示にならないので、以下の通り`CGFloat.leastNonzeroMagnitude`を指定することに注意。

```ViewController.swift
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return .leastNonzeroMagnitude
}
```
以上で、期待通りのTable表示になりました！

## 全コード

```ViewController.swift
import UIKit

final class ViewController: UIViewController {
    /// TableViewに表示するコンテンツの配列
    private var contents: [Content] = sampleContent
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // contentsを取得する処理とか...
    }
}

// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
    
    // 行間のスペースを実現するために、セクションを使用
    // 1セクション = 1行 にしてヘッダーで余白を表現している
    func numberOfSections(in tableView: UITableView) -> Int {
        return contents.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1 // 要素数はsectionで表現するため、rowは常に1個のみ
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Ptorotype Cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        // セルの設定を行う...

        return cell
    }
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 8  // Cell間に設けたい余白の高さを指定
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let marginView = UIView()
        marginView.backgroundColor = .clear  // 背景色を透過させる
        return marginView
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return .leastNonzeroMagnitude  // 完全に表示させないようにする
    }
}
```

参考：https://stackoverflow.com/questions/6216839/how-to-add-spacing-between-uitableviewcell