LoginSignup
4
3

More than 3 years have passed since last update.

【Swift】UITableView等で0件(empty)の時の表示方法まとめ

Posted at

DZNEmptyDataSet

超有名ライブラリ
Objective-C製で、Method Swizzling を使うことで、UITableViewDataSouceのメソッドを乗っ取ってDataが空の場合は別の処理が呼ばれるようになっている。
Method Swizzlingを使わずにこれをSwiftで実現できたらいいのになぁと思う。

DZNEmptyDataSet: GitHub
https://github.com/dzenbot/DZNEmptyDataSet

EmptyStateKit

Swift製で、Empty用のDelegateとDataSourceをセットして、Dataが空の場合にshow()を叩くことでEmpty用のViewを表示させるようになっている。
魔法が使われていないのでコードをみたら実装がだいたいわかる。
これならライブラリを使わなくてもいいけど、使うと全体的に実装が強制的に同じ様になるんでいいかも。

EmptyStateKit: GitHub
https://github.com/alberdev/EmptyStateKit

自分でやるなら

UITableViewのtableHeaderViewにEmptyViewを入れておいて、Dataが空かどうかによってSizeを設定することでEmptyViewを表示させたり非表示にしたりする。
以下Sampleです。Protocol作ってみてますが、なくてもいいっちゃいいです。ViewControllerには4行ぐらい書けばいいので。

TableHeaderViewが使えないならFooterを使って、それでもだめだったり、CollectionViewだったらEmptyViewをTableViewにaddSubViewして、Hiddenで管理するようにしてもいいですね。違いは、スクロールできないぐらいなので。

protocol TableViewEmptyDisplayable {

    associatedtype EmptyViewType: EmptyView

    var emptyView: EmptyViewType { get }
    func showEmptyView()
    func hideEmptyView()
}

extension TableViewEmptyDisplayable {

    func showEmptyView() {
        self.emptyView.bounds.size = EmptyViewType.size
    }

    func hideEmptyView() {
        self.emptyView.bounds.size = .zero
    }
}

protocol EmptyView: UIView {
    static var size: CGSize { get }
}

class EmptyViewImpl: UIView, EmptyView {

    static let size = CGSize(width: UIScreen.main.bounds.width, height: 400)
}

class SampleViewController: UIViewController, TableViewEmptyDisplayable {

    typealias EmptyViewType = EmptyViewImpl

    @IBOutlet weak var tableView: UITableView!

    let emptyView: EmptyViewType = EmptyViewImpl()

    private var data: [Int] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.tableHeaderView = self.emptyView
    }
}

extension SampleViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.data.isEmpty {
            self.showEmptyView()
        } else {
            self.hideEmptyView()
        }
        return self.data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell()
    }
}

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3