214 lines
8.5 KiB
Swift
214 lines
8.5 KiB
Swift
//
|
||
// EmptyDataSet.swift
|
||
// JiuLaiBao
|
||
//
|
||
// Created by 霹雳火 on 01/06/2018.
|
||
// Copyright © 2018 GuoXiaoMei. All rights reserved.
|
||
//
|
||
|
||
import Foundation
|
||
import RxSwift
|
||
import UIKit
|
||
|
||
private var emptyDataSetAssociatedKey: UInt8 = 0
|
||
|
||
public extension DLWrapper where Base: UIScrollView {
|
||
/// DLEmptyDataSet
|
||
var emptyDataSet: DLEmptyDataSet? { objc_getAssociatedObject(base, &emptyDataSetAssociatedKey) as? DLEmptyDataSet }
|
||
|
||
///
|
||
/// - Parameters:
|
||
/// - customEmptyHandler: 自定义Empty样式回调,可以对empty进行设置
|
||
/// - customButtonDidTap: 自定义按钮点击回调
|
||
/// - didTapRefresh: 网络失败按钮点击事件回调
|
||
/// - Returns: DLEmptyDataSet
|
||
@discardableResult
|
||
func addEmptyDataSet(customEmptyHandler: ((DLEmptyDataSet) -> Void)? = nil,
|
||
customButtonDidTap: (() -> Void)? = nil,
|
||
didTapRefresh: (() -> Void)? = nil) -> DLEmptyDataSet {
|
||
let emptyDataSet = DLEmptyDataSet(scrollView: base)
|
||
emptyDataSet.didTapRefresh = didTapRefresh
|
||
emptyDataSet.customDidTap = customButtonDidTap
|
||
customEmptyHandler?(emptyDataSet)
|
||
objc_setAssociatedObject(base, &emptyDataSetAssociatedKey, emptyDataSet, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||
return emptyDataSet
|
||
}
|
||
}
|
||
|
||
public struct EmptyDataSetConfig {
|
||
static public var titleColor = UIColor(hexStr: "#666666")
|
||
static public var detailColor = UIColor(hexStr: "#999999")
|
||
static public var emptyNoDataTitle = "oapp_EmptyNoData"
|
||
static public var emptyNoDataDetail = ""
|
||
static public var emptyNoDataImage = UIImage(named: "empty_data")
|
||
static public var emptyNetworkErrorTitle = "请检查网络连接"
|
||
static public var emptyNetworkErrorDetail = ""
|
||
static public var emptyNetworkErrorImage = UIImage(named: "empty_network")
|
||
static public var emptyReloadButtonImage = UIImage(named: "empty_reload")
|
||
static public var reloadButtonTitle = "重新加载"
|
||
static public var customButtonTitle = ""
|
||
static public var backgroundColor: UIColor = .clear
|
||
static public var spaceHeight: CGFloat = 15.0
|
||
|
||
/// 重置
|
||
public static func resetConfig() {
|
||
titleColor = UIColor(hexStr: "#666666")
|
||
detailColor = UIColor(hexStr: "#999999")
|
||
emptyNoDataTitle = "暂无数据"
|
||
emptyNoDataDetail = ""
|
||
emptyNoDataImage = UIImage(named: "empty_data")
|
||
emptyNetworkErrorTitle = "请检查网络连接"
|
||
emptyNetworkErrorDetail = ""
|
||
emptyNetworkErrorImage = UIImage(named: "empty_network")
|
||
emptyReloadButtonImage = UIImage(named: "empty_reload")
|
||
customButtonTitle = ""
|
||
backgroundColor = .clear
|
||
}
|
||
}
|
||
|
||
public class DLEmptyDataSet: NSObject {
|
||
|
||
private var disposeBag = DisposeBag()
|
||
private weak var scrollView: UIScrollView!
|
||
private var refreshStatus: RefreshStatus?
|
||
private var isEmptyVariable = BehaviorSubject<Bool?>(value: nil)
|
||
// 是否开始就显示empty占位图
|
||
private var shouldBeForcedToDisplay = false
|
||
public var titleColor = EmptyDataSetConfig.titleColor
|
||
public var detailColor = EmptyDataSetConfig.detailColor
|
||
public var emptyNoDataTitle = EmptyDataSetConfig.emptyNoDataTitle
|
||
public var emptyNoDataDetail = EmptyDataSetConfig.emptyNoDataDetail
|
||
public var emptyNoDataImage = EmptyDataSetConfig.emptyNoDataImage
|
||
public var emptyNetworkErrorTitle = EmptyDataSetConfig.emptyNetworkErrorTitle
|
||
public var emptyNetworkErrorDetail = EmptyDataSetConfig.emptyNetworkErrorDetail
|
||
public var emptyNetworkErrorImage = EmptyDataSetConfig.emptyNetworkErrorImage
|
||
public var emptyReloadButtonImage = EmptyDataSetConfig.emptyReloadButtonImage
|
||
public var reloadButtonTitle = EmptyDataSetConfig.reloadButtonTitle
|
||
public var customButtonTitle = EmptyDataSetConfig.customButtonTitle
|
||
public var backgroundColor: UIColor = EmptyDataSetConfig.backgroundColor
|
||
public var spaceHeight: CGFloat = EmptyDataSetConfig.spaceHeight
|
||
public var offsetY: CGFloat = 0 {
|
||
didSet {
|
||
scrollView.reloadEmptyDataSet()
|
||
}
|
||
}
|
||
|
||
public var didTapRefresh: (() -> Void)?
|
||
public var customDidTap: (() -> Void)?
|
||
|
||
required public init(scrollView: UIScrollView) {
|
||
super.init()
|
||
self.scrollView = scrollView
|
||
scrollView.emptyDataSetSource = self
|
||
scrollView.emptyDataSetDelegate = self
|
||
isEmptyVariable.asObservable().subscribe(onNext: { [unowned self] value in
|
||
if let _ = value {
|
||
self.scrollView.reloadEmptyDataSet()
|
||
}
|
||
}).disposed(by: disposeBag)
|
||
}
|
||
|
||
public func update(status: RefreshStatus?, isEmpty: Bool, shouldForcedDisplay: Bool = false) {
|
||
refreshStatus = status
|
||
shouldBeForcedToDisplay = shouldForcedDisplay
|
||
isEmptyVariable.onNext(isEmpty)
|
||
}
|
||
|
||
public func reset() {
|
||
shouldBeForcedToDisplay = false
|
||
refreshStatus = nil
|
||
isEmptyVariable.onNext(false)
|
||
}
|
||
}
|
||
|
||
extension DLEmptyDataSet: EmptyDataSetSource, EmptyDataSetDelegate {
|
||
|
||
// MARK: DZNEmptyDataSetSource
|
||
public func title(forEmptyDataSet _: UIScrollView) -> NSAttributedString? {
|
||
let text = refreshStatus == .invalidData ? emptyNetworkErrorTitle : emptyNoDataTitle
|
||
let attributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 13),
|
||
.foregroundColor: titleColor]
|
||
return NSAttributedString(string: text, attributes: attributes)
|
||
}
|
||
|
||
public func description(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
|
||
let text = refreshStatus == .invalidData ? emptyNetworkErrorDetail : emptyNoDataDetail
|
||
let attributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 13),
|
||
.foregroundColor: detailColor]
|
||
return NSAttributedString(string: text, attributes: attributes)
|
||
}
|
||
|
||
public func buttonTitle(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> String? {
|
||
return refreshStatus == .invalidData ? " \(reloadButtonTitle) " : customButtonTitle.isEmpty ? nil : " \(customButtonTitle) "
|
||
}
|
||
|
||
public func buttonAttributedTitle(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> NSAttributedString? {
|
||
// let errorAttri = NSAttributedString(string: "oapp_Reload".localizedString,
|
||
// font: UIFont.systemFont(ofSize: 15),
|
||
// color: UIColor.dl.rgb666666)
|
||
// return refreshStatus == .invalidData ? errorAttri : nil
|
||
return nil
|
||
}
|
||
|
||
public func image(forEmptyDataSet _: UIScrollView) -> UIImage? {
|
||
return refreshStatus == .invalidData ? emptyNetworkErrorImage : emptyNoDataImage
|
||
}
|
||
|
||
// public func buttonImage(forEmptyDataSet scrollView: UIScrollView!, for state: UIControl.State) -> UIImage! {
|
||
// return refreshStatus == .invalidData ? emptyReloadButtonImage : nil
|
||
// }
|
||
|
||
public func backgroundColor(forEmptyDataSet _: UIScrollView) -> UIColor? {
|
||
return backgroundColor
|
||
}
|
||
|
||
// MARK: DZNEmptyDataSetDelegate
|
||
public func emptyDataSetShouldDisplay(_: UIScrollView) -> Bool {
|
||
// 判断是否正在刷新
|
||
guard refreshStatus != nil,
|
||
let isDisplay = try? isEmptyVariable.value() else {
|
||
return false
|
||
}
|
||
// 网络请求错误或者请求数据为空
|
||
return isDisplay
|
||
}
|
||
|
||
public func emptyDataSetShouldAllowTouch(_ scrollView: UIScrollView) -> Bool {
|
||
return true
|
||
}
|
||
|
||
public func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView) -> Bool {
|
||
return true
|
||
}
|
||
|
||
public func emptyDataSet(_ scrollView: UIScrollView, didTapView view: UIView) {
|
||
|
||
}
|
||
|
||
public func emptyDataSet(_ scrollView: UIScrollView, didTapButton button: UIButton) {
|
||
if customButtonTitle.isEmpty {
|
||
reset()
|
||
didTapRefresh?()
|
||
}
|
||
else {
|
||
customDidTap?()
|
||
}
|
||
}
|
||
|
||
public func emptyDataSetWillAppear(_ scrollView: UIScrollView) {
|
||
scrollView.contentOffset = CGPoint()
|
||
}
|
||
|
||
public func verticalOffset(forEmptyDataSet scrollView: UIScrollView) -> CGFloat {
|
||
return offsetY
|
||
}
|
||
|
||
public func spaceHeight(forEmptyDataSet scrollView: UIScrollView) -> CGFloat {
|
||
return spaceHeight
|
||
}
|
||
|
||
@objc public func emptyDataSetShouldBeForcedToDisplay(_ scrollView: UIScrollView) -> Bool {
|
||
return shouldBeForcedToDisplay
|
||
}
|
||
}
|