Posted at

[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