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()
}
}