はじめに (対象読者・この記事でわかること)

本記事は、iOSアプリ開発でUITableViewを利用している中級者〜上級者を対象としています。特に、画面下部に一定の余白を確保したいデザイン要件がある方や、スクロール時にフッターが隠れないようにしたい方に最適です。この記事を読むことで、TableViewのcontentInsettableFooterView、さらにAuto Layoutを組み合わせた空白領域の作り方が具体的に理解でき、実装コードをそのままプロジェクトに組み込むことが可能になります。背景にあるレイアウトの原理や、よくある落とし穴とその回避策も合わせて紹介するので、同様の課題に直面した際にすぐに対応できるようになります。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。
- Swiftの基本文法とXcodeでのビルド経験
- UIKitの基礎(UIView、UIViewController、Auto Layout)
- UITableViewの基本的な使い方(dataSource、delegateの設定)

TableViewの下に空白を設ける必要性と基本概念

iOSアプリの多くは、画面の最下部にタブバーやホームインジケータが配置されることがあります。これらのシステム領域とTableViewのコンテンツが重なると、ユーザーが項目をタップしにくくなるだけでなく、デザイン上の不整合も生じます。そのため、TableViewの下部に一定の余白(スペーサー)を設けることは、ユーザーエクスペリエンスを向上させる上で重要です。
余白を実装する主な方法は次の通りです。

  1. contentInset を利用してスクロール領域全体に余白を付加する
  2. tableFooterView に高さだけの空の UIView を設定する
  3. Auto Layout で TableView の底部に制約を付け、下に余白用のコンテナビューを配置する

それぞれの手法は、実装のシンプルさ、動的な高さ変更への対応、他の UI コンポーネントとの相性に違いがあります。たとえば、contentInset はスクロール時に自動で余白が適用されますが、キーボード表示時の調整が別途必要になることがあります。一方、tableFooterView は固定高さの空白を提供しつつ、スクロール領域外のビューとして扱われるため、キーボードや safeArea との衝突を回避しやすいです。Auto Layout を用いた方法は、Storyboard や SwiftUI と組み合わせたときに柔軟性が高く、複数のビューが混在するレイアウトでも一貫した余白を保てます。

本稿では、最も汎用性が高く、コード量が少ない「tableFooterView を利用した空白作成」をメインに解説し、併せて contentInset と Auto Layout の実装例も紹介します。これにより、プロジェクトの要件や好み、既存コードベースに合わせて最適な手法を選択できるようになります。

実装手順:TableViewのフッターやコンテントインセット、カスタムセルで空白を作る方法

実際に空白領域を作成する手順は以下の通りです。ここでは、Storyboard を使わずにコードだけで完結する方法と、Storyboard で制約を設定する方法の2パターンを示します。

ステップ1:tableFooterView に高さだけの空 UIView を設定する

Swift
import UIKit class SampleTableViewController: UITableViewController { // 空白の高さ(例: 100pt) private let bottomSpacing: CGFloat = 100.0 override func viewDidLoad() { super.viewDidLoad() configureTableFooter() } private func configureTableFooter() { // 高さだけを持つ空の UIView を作成 let footer = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: bottomSpacing)) // 背景色は透明に(必要なら好きな色に変更可) footer.backgroundColor = .clear // TableView のフッターとして設定 tableView.tableFooterView = footer } // MARK: - UITableViewDataSource override func numberOfSections(in tableView: UITableView) -> Int { 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 // デモ用データ数 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell") cell.textLabel?.text = "行 \(indexPath.row + 1)" return cell } }

ポイント
- tableFooterView は TableView のコンテンツ領域の最後に表示されるため、スクロール領域の一部として扱われます。
- 高さだけを指定すれば、ユーザーがスクロールしたときに余白が自然に現れます。
- backgroundColor.clear にすれば、視覚的に空白だけが確保された状態になります。

ステップ2:contentInset を併用して安全領域と合わせる

フッターだけで足りないケース(例:キーボード表示時に余白が足りなくなる)では、contentInset でも微調整を行います。

Swift
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 常に safeArea の下端に余白を確保 let bottomInset = bottomSpacing + view.safeAreaInsets.bottom tableView.contentInset.bottom = bottomInset tableView.scrollIndicatorInsets.bottom = bottomInset }

ポイント
- view.safeAreaInsets.bottom を加算することで、iPhone X 系列のホームインジケータ領域と重ならないようになります。
- scrollIndicatorInsets も同様に設定すると、スクロールインジケータ(サイドバー)が余白部分に隠れなくなります。

ステップ3:Storyboard で Auto Layout を利用する場合

Storyboard でレイアウトを管理しているプロジェクトでは、以下の手順で余白ビューを追加できます。

  1. TableView の下に UIView を配置
    - 高さ制約を 100 に設定(もしくは変数で調整)。
    - 下端は Safe Area に対して 0 の制約を付与。

  2. UIView の背景色を透明に(もしくはデザインに合わせた色)。

  3. TableView の bottom constraint を UIView の top に接続

この構成により、Storyboard 上で余白が視覚的に確認でき、Interface Builder のプレビューでも正しく表示されます。

ハマった点やエラー解決

発生した問題 原因 解決策
フッターの高さが反映されない tableFooterView に設定した UIView の幅が tableView.bounds.width ではなく 0 になることがある(Layout がまだ確定していない) viewDidLayoutSubviews でフッターを再設定する。
キーボードが表示されたときに余白が縮む contentInset の設定がキーボード通知で上書きされている keyboardWillShow / keyboardWillHidecontentInset.bottom に余白分を足すロジックを追加する。
SafeArea へ余白が重なる view.safeAreaInsets.bottom が取得できるタイミングが viewDidLoad の時点で 0 になる viewSafeAreaInsetsDidChange() で余白再計算を行う。

解決策のコード例(キーボード対策)

Swift
override func viewDidLoad() { super.viewDidLoad() registerKeyboardNotifications() } private func registerKeyboardNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) } @objc private func keyboardWillShow(_ notification: Notification) { guard let kbFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } let overlap = kbFrame.height - view.safeAreaInsets.bottom let inset = max(bottomSpacing, overlap) tableView.contentInset.bottom = inset tableView.scrollIndicatorInsets.bottom = inset } @objc private func keyboardWillHide(_ notification: Notification) { let inset = bottomSpacing + view.safeAreaInsets.bottom tableView.contentInset.bottom = inset tableView.scrollIndicatorInsets.bottom = inset }

まとめ

本記事では、UITableView の下部に一定の高さの空白を作る具体的な実装手順を解説しました。
- tableFooterView に高さだけの空 UIView を設定すれば、最小限のコードで確実に余白が確保できます。
- contentInset と safeArea を組み合わせることで、キーボード表示や iPhone のホームインジケータ領域との衝突を防げます。
- Storyboard で Auto Layout を使用すれば、視覚的に余白を管理でき、デザイン担当者との協働がスムーズになります。

これらの手法を組み合わせることで、ユーザーが快適に操作できるレイアウトを実現でき、アプリの見た目と操作性の両方を向上させることができます。

参考資料