tableView空數據問題
一般項目中tableView若數據為空時會有一個提示示意圖
為了更好的管理這種提示示意圖,筆者利用extension進行了簡單的拓展
解決思路
利用swift面向協議的特點,使用協議來進行設置。
- 設計空視圖協議
- tableView設置空視圖代理
- 每次重繪tableView時判斷添加或移除空數據提示圖
具體實現
- 空視圖協議,遵守協議必須實現showEmtpy屬性
private let EmptyViewTag = 12345;
protocol EmptyViewProtocol: NSObjectProtocol {
///用以判斷是會否顯示空視圖
var showEmtpy: Bool {get}
///配置空數據提示圖用於展示
func configEmptyView() -> UIView?
}
extension EmptyViewProtocol {
func configEmptyView() -> UIView? {
return nil
}
}
- tableView擴展配置,實現空數據示意圖展示判斷
DispatchQueue.once和BQTool.exchangeMethod是只執行一次方法交換操作,具體實現可看源碼
func setEmtpyViewDelegate(target: EmptyViewProtocol) {
self.emptyDelegate = target
DispatchQueue.once(#function) {
BQTool.exchangeMethod(cls: self.classForCoder, targetSel: #selector(self.layoutSubviews), newSel: #selector(self.re_layoutSubviews))
}
}
@objc func re_layoutSubviews() {
self.re_layoutSubviews()
if self.emptyDelegate!.showEmtpy {
guard let view = self.emptyDelegate?.configEmptyView() else {
return;
}
if let subView = self.viewWithTag(EmptyViewTag) {
subView.removeFromSuperview()
}
view.tag = EmptyViewTag;
self.addSubview(view)
} else {
guard let view = self.viewWithTag(EmptyViewTag) else {
return;
}
view .removeFromSuperview()
}
}
//MARK:- ***** Associated Object *****
private struct AssociatedKeys {
static var emptyViewDelegate = "tableView_emptyViewDelegate"
}
private var emptyDelegate: EmptyViewProtocol? {
get {
return (objc_getAssociatedObject(self, &AssociatedKeys.emptyViewDelegate) as! EmptyViewProtocol)
}
set (newValue){
objc_setAssociatedObject(self, &AssociatedKeys.emptyViewDelegate, newValue!, .OBJC_ASSOCIATION_RETAIN)
}
}
示例代碼
//關鍵部分代碼
class ViewController: UIViewController , EmptyViewProtocol {
private var datas: Array<Dictionary<String, String>>?
/// 空數據提示圖
private var label: UILabel?
var showEmtpy: Bool {
get {
if let data = self.datas {
return data.count == 0
}
return true
}
}
override func viewDidLoad() {
super.viewDidLoad()
let tableView: UITableView = ...
tableView.setEmtpyViewDelegate(target: self)
self.view.addSubview(tableView)
}
func configEmptyView() -> UIView? {
if let view = self.label {
return view
}
let lab = UILabel(frame: CGRect(x: 100, y: 300, width: 200, height: 30))
lab.text = "this is a test"
lab.textAlignment = .center
self.label = lab
return lab
}
}
效果圖如下
最后
- 該設計較為簡單方便管理,若有不妥之處望指出
- 相關代碼請前往swiftCustomControl查看